def get_cams_info(self): l_cams_info = dict() l_cams_info["extinction_coeffs"] = [] if self.has_cams_info(): l_count = int( xml_tools.get_attribute( self.root, "/Earth_Explorer_Header/Variable_Header/Specific_Product_Header/Extinction_Coefs_List", "count")) # loop on coefficients for i in range(0, l_count): extcoeffs = {} l_string = str(i + 1) # retrieve description name and value extcoeffs["Description"] = xml_tools.get_xml_string_value( self.root, "/Earth_Explorer_Header/Variable_Header/" + "Specific_Product_Header/Extinction_Coefs_List/Extinction_Coef[@n=" + l_string + "]/Description") extcoeffs["Name"] = xml_tools.get_xml_string_value( self.root, "/Earth_Explorer_Header/Variable_Header/Specific_Product_Header/" + "Extinction_Coefs_List/Extinction_Coef[@n=" + l_string + "]/Name") extcoeffs["Values"] = xml_tools.as_string_list( xml_tools.get_xml_string_value( self.root, "/Earth_Explorer_Header/Variable_Header/Specific_Product_Header/" + "Extinction_Coefs_List/Extinction_Coef[@n=" + l_string + "]/Values")) l_cams_info["extinction_coeffs"].append(extcoeffs) l_cams_info["rh_dep"] = xml_tools.get_xml_bool_value( self.root, "//Earth_Explorer_Header/Variable_Header/Specific_Product_Header/RH_dep" ) l_cams_info["rh_tab"] = xml_tools.as_string_list( xml_tools.get_xml_string_value( self.root, "//Earth_Explorer_Header/Variable_Header/Specific_Product_Header/RH_Tab" )) return l_cams_info
def run(self, dict_of_input, dict_of_output): LOGGER.info("Cirrus Correction start") cirrus_working = dict_of_input.get( "AppHandler").get_directory_manager().get_temporary_directory( "CirrusCorrProc_", do_always_remove=True) refres_name = dict_of_input.get( "Plugin").CirrusCorrectionReferenceResolution refres_idx = 9999 bands_definition = dict_of_input.get("Plugin").BandsDefinitions for i in range(0, len(bands_definition.ListOfL2Resolution)): if bands_definition.ListOfL2Resolution[i] == refres_name: refres_idx = i # TODO test refres_idx result = {} ref_result = self._gamma_compute_at_res(dict_of_input, dict_of_output, refres_idx, cirrus_working) result[bands_definition.ListOfL2Resolution[refres_idx]] = ref_result if ref_result[2]: LOGGER.info("Cirrus flag enabled on reference resolution") l_gammamean = ref_result[3] * ref_result[4] l_nbgamma = ref_result[3] for i in range(0, len(bands_definition.ListOfL2Resolution)): if bands_definition.ListOfL2Resolution[i] != refres_name: res_result = self._gamma_compute_at_res( dict_of_input, dict_of_output, i, cirrus_working) result[bands_definition.ListOfL2Resolution[i]] = res_result l_gammamean = l_gammamean + res_result[3] * res_result[4] l_nbgamma = l_nbgamma + res_result[3] l_gammamean = l_gammamean / l_nbgamma l_gamma_max = float( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionMaxGammaValue")) l_gamma_min = float( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionMinGammaValue")) # Boundary set for gamma if l_gammamean > l_gamma_max: l_gammamean = l_gamma_max if l_gammamean < l_gamma_min: l_gammamean = l_gamma_min LOGGER.info("Gamma : " + str(l_gammamean)) # Apply correction for i in range(0, len(bands_definition.ListOfL2Resolution)): l_res = bands_definition.ListOfL2Resolution[i] corrected_toa = os.path.join(cirrus_working, "toac_" + l_res + ".tif") l_gammaswir = l_gammamean * float( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionSWIRGammaFactor")) l_l2bandcodes = bands_definition.get_list_of_l2_band_code( l_res) swir_band_list = xml_tools.as_string_list( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionSWIRBandCodes")) # Param of cirrus apply app param_cirrus_apply = { "l2toa": dict_of_output["AtmoAbsIPTOA_" + l_res], "l2edg": dict_of_input.get("L1Reader").get_value("L2EDGOutputList") [i], "l2dtm": dict_of_input.get("DEM").ALTList[i], "l2cirrus": result[l_res][0], "cirrusmask": result[l_res][1], "resolution": bands_definition.get_l1_resolution(l_res), "maxdistance": float( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionMaxDistance")), "thresholdgain": float( dict_of_input.get("L2COMM").get_value( "CirrusMaskThresholdGain")), "thresholdoffset": float( dict_of_input.get("L2COMM").get_value( "CirrusMaskThresholdOffset")), "thresholdfactor": float( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionThresholdFactor")), "gammamean": l_gammamean, "swirgammafactor": l_gammaswir, "maxreflectance": float( dict_of_input.get("L2COMM").get_value( "CirrusMaxReflectance")), "bandcodelist": l_l2bandcodes, "swirbandcodelist": swir_band_list, "correctedtoa": corrected_toa } app = OtbAppHandler( "CirrusCorrectionApply", param_cirrus_apply, write_output=(False or is_croco_on("cirruscorrection"))) self._l2_pipeline.add_otb_app(app) dict_of_output["L2TOA_" + l_res] = app.getoutput().get("correctedtoa") else: LOGGER.info( "Cirrus flag disabled on reference resolution, no cirrus correction" ) # return cirrus corrected flag dict_of_output["CirrusCorrected"] = ref_result[2] return ref_result[2]
def _gamma_compute_at_res(self, dict_of_input, dict_of_output, p_res, p_working): bands_definition = dict_of_input.get("Plugin").BandsDefinitions l_res = bands_definition.ListOfL2Resolution[p_res] LOGGER.info("Cirrus gamma compute at res " + l_res + " start") # ---------- Resample L1 Cirrus to resolution --------------- l1cirrus_resampled = os.path.join(p_working, "toacirrus_" + l_res + ".tif") param_l1cirrus_resample = { "dtm": dict_of_input.get("DEM").ALTList[p_res], "im": dict_of_input.get("L1Reader").get_value("L1TOACirrusImage"), "interp": "bco", "out": l1cirrus_resampled } app_l1cirrus_resamp = OtbAppHandler("Resampling", param_l1cirrus_resample, write_output=True) # ---------- Resample Cirrus cloud to resolution --------------- cld_cirrus_resampled = dict_of_output[CLOUD_MASK_CIRRUS + "_" + l_res] cirrusmask_resampled = os.path.join(p_working, "cirrusmask_" + l_res + ".tif") # ---------- Resample All cloud to resolution --------------- cld_all_resampled = dict_of_output[CLOUD_MASK_ALL + "_" + l_res] allmask_resampled = os.path.join(p_working, "allmask_" + l_res + ".tif") # ---------- Resample Refl cloud to resolution --------------- cld_refl_resampled = dict_of_output[CLOUD_MASK_REFL + "_" + l_res] allreflresampled = os.path.join(p_working, "reflmask_" + l_res + ".tif") # ----- Caching of L2TOA l2toa_cach = os.path.join(p_working, "l2toa_" + l_res + ".tif") #Write to caching write_images([ cld_cirrus_resampled, cld_all_resampled, cld_refl_resampled, dict_of_output["L2TOA_" + l_res] ], [ cirrusmask_resampled, allmask_resampled, allreflresampled, l2toa_cach ]) # Update dict clean_pipe(dict_of_output[CLOUD_MASK_CIRRUS + "_" + l_res]) clean_pipe(dict_of_output[CLOUD_MASK_ALL + "_" + l_res]) clean_pipe(dict_of_output[CLOUD_MASK_REFL + "_" + l_res]) clean_pipe(dict_of_output["L2TOA_" + l_res]) dict_of_output[CLOUD_MASK_CIRRUS + "_" + l_res] = cirrusmask_resampled dict_of_output[CLOUD_MASK_ALL + "_" + l_res] = allmask_resampled dict_of_output[CLOUD_MASK_REFL + "_" + l_res] = allreflresampled dict_of_output["L2TOA_" + l_res] = l2toa_cach # --------------------- Gamma compute for the resolution # construct band list gamm_band_list = xml_tools.as_string_list( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionGammaBandCodes")) l_l2bandcodes = bands_definition.get_list_of_l2_band_code(l_res) l_resbandlist = [] for i in range(0, len(l_l2bandcodes)): if l_l2bandcodes[i] in gamm_band_list: l_resbandlist.append(str(i)) cirrus_mask = os.path.join(p_working, "cirrus_corr_mask_" + l_res + ".tif") param_gamma_compute = { "l2toa": l2toa_cach, "l2edg": dict_of_input.get("L1Reader").get_value("L2EDGOutputList")[p_res], "l2dtm": dict_of_input.get("DEM").ALTList[p_res], "l2cirrus": app_l1cirrus_resamp.getoutput().get("out"), "bandlist": l_resbandlist, "cloudcirrus": cirrusmask_resampled, "cloudall": allmask_resampled, "cloudrefl": allreflresampled, "cirrusminpixinlist": int( dict_of_input.get("L2COMM").get_value( "CirrusCorrectionMinPixInList")), "mask": cirrus_mask + ":uint8" } gamma_compute_app = OtbAppHandler("GammaCompute", param_gamma_compute, write_output=True) cirr_flag = bool(gamma_compute_app.getoutput()["cirrusflag"]) gamma = float(gamma_compute_app.getoutput()["gamma"]) del gamma_compute_app del app_l1cirrus_resamp return [ l1cirrus_resampled, cirrus_mask, cirr_flag, len(l_resbandlist), gamma ]
def read(self, product_info, app_handler, l2comm, dem, pReadL1Mode): """product_info,plugin, l2comm,mode :param product_info: L1ImageInformationsBase :param pReadL1Mode: ReadL1ModeType :return: """ product_filename = product_info.HeaderFilename working_dir = app_handler.get_directory_manager( ).get_temporary_directory("L1Read_", do_always_remove=True) self._plugin.initialize(app_handler) self._GIPPL2COMMHandler = l2comm LOGGER.info("Start Sentinel2 L1 ImageFileReader ...") self._ReadL1Mode = pReadL1Mode self._dem = dem # -------------------------------------- # Check the extension of th efile. For Muscate, must be .XML (in upper case) IsValidSatellite = (product_info.HeaderHandler is not None) if not IsValidSatellite: raise MajaPluginSentinel2Exception( "The file <{}> is not a valid Sentinel2 L1 product.".format( product_filename)) # Check the validity with the schema lSchemaLocationFile = os.path.join( app_handler.get_schemas_root_install_dir(), self._plugin.MAJA_INSTALL_SCHEMAS_L1PRODUCT_FILE) if app_handler.get_validate_schemas(): # remplacer par un appel à pylint ? un check xml result = check_xml(product_filename, xsd_file=lSchemaLocationFile) if not result: raise MajaPluginSentinel2Exception( "The xml file <{}> is not conform with its schema <{}> !, Log of execution :{}" .format(product_filename, lSchemaLocationFile, str(result))) # -------------------------------------- # Load the header tile file in the xml tile handler to read tile information xmlTileFilename = product_info.xmlTileFilename # ******************************************************************************************************* # TOA & masks Reader connection # ******************************************************************************************************* l_BandsDefinitions = self._plugin.BandsDefinitions # BandsDefinitions l_ListOfTOAImageFileNames = product_info.HeaderHandler.get_list_of_toa_images( ) # ListOfStrings l_SatPixFileNames = product_info.TileHandler.ListOfSaturatedPixelsHeaderFileName # ListOfStrings l_DefectivPixFileNames = product_info.TileHandler.ListOfDefectivPixelsHeaderFileName # ListOfStrings l_ZoneMaskFileNames = product_info.TileHandler.ListOfDetFootPrintHeaderFileName # ListOfStrings l_NoDataMaskFileNames = product_info.TileHandler.ListOfNoDataPixelsHeaderFileName # ListOfStrings l_ListOfTOABandCode = product_info.HeaderHandler.get_list_of_band_codes( ) # ListOfStrings l_ListOfL1Resolution = l_BandsDefinitions.ListOfL1Resolution # ListOfStrings l_ListOfL2Resolution = l_BandsDefinitions.ListOfL2Resolution # ListOfStrings l_NbL1Res = len(l_ListOfL1Resolution) # int l_NbL2Res = len(l_ListOfL2Resolution) # int l_NbBand = len(l_ListOfTOAImageFileNames) # int # TODO: check ConfigUserCameraXMLFileHandler # TODO; check GetL2CoarseResolution grep L2CoarseResolution l_Areas = dem.L2Areas l_L2CoarseArea = dem.CoarseArea l_L2CoarseResolution = int(round(dem.CoarseArea.spacing[0])) LOGGER.debug(l_L2CoarseResolution) l_L1NoData = product_info.L1NoData l_ReflectanceQuantificationValue = product_info.ReflectanceQuantification l_RealL1NoData = l_L1NoData * l_ReflectanceQuantificationValue # RealNoDataType if (len(l_ListOfTOABandCode) != len(l_ListOfTOAImageFileNames)) or ( len(l_ListOfTOABandCode) != len(l_SatPixFileNames)) or ( len(l_ListOfTOABandCode) != len(l_DefectivPixFileNames)): raise MajaPluginSentinel2Exception( "Sentinel2L1ImageFileReader.CanRead: Internal error: The number of image file, sat file and band code are different !" ) # =======> GENERATE TOA CACHING # # * Get calibration coeffs if activated l_reflectanceMultiplicationValues = [] # ListOfDoubles if xml_tools.as_bool(l2comm.get_value("CalAdjustOption")): l_factors = xml_tools.as_float_list( l2comm.get_value("CalAdjustFactor")) if len(l_factors) != len(l_ListOfTOABandCode): raise MajaPluginSentinel2Exception( "Not the same number of Calibration coeffs than L1 bands ( {}, {} )" .format(len(l_factors), len(l_ListOfTOABandCode))) for i in range(len(l_ListOfTOABandCode)): l_reflectanceMultiplicationValues.append( l_ReflectanceQuantificationValue * l_factors[i]) else: for i in range(len(l_ListOfTOABandCode)): l_reflectanceMultiplicationValues.append( l_ReflectanceQuantificationValue) l_ProjectionRef = self._dem.ProjRef self.generate_toa(l_ListOfTOAImageFileNames, l_reflectanceMultiplicationValues, working_dir) # string # *********************************************************************************************************** # Generate EDG at L2coarse and L2 resolutions # *********************************************************************************************************** self.generate_edg_images_from_toa(l_ListOfTOAImageFileNames, working_dir) # *********************************************************************************************************** # Get the bounding box of each L1 resolution # *********************************************************************************************************** # list of bounding box per resolution l_L1BoundingBoxMap = {} # BoundingBoxMapType for res in range(l_NbL1Res): curRes = l_ListOfL1Resolution[res] # string l_IntResolution = l_BandsDefinitions.get_l1_resolution(curRes) # Read the bounding box for the current resolution l_BoundingBox = product_info.TileHandler.get_geoposition_boundingbox( l_IntResolution) # BoundingBoxType LOGGER.debug( "S2 Geoposition BoundingBox computed: xmin, ymin, xmax, ymax: %s, %s, %s, %s.", l_BoundingBox.xmin, l_BoundingBox.ymin, l_BoundingBox.xmax, l_BoundingBox.ymax) # Store the bounding box per resolution l_L1BoundingBoxMap[curRes] = l_BoundingBox # *********************************************************************************************************** # *********************************************************************************************************** # *********************************************************************************************************** # START READ L1 for ALGORITHMS # *********************************************************************************************************** # *********************************************************************************************************** # *********************************************************************************************************** if pReadL1Mode == ReadL1Mode.READ_L1_MODE_FOR_ALGORITHMS: # -------------------------------------- # Get information of areas (footprint) of the product (Origin, Spacing and Size for L2 and L2Coarse resolution) # -------------------------------------- l_L2Dems = dem.ALTList l_CoarseDem = dem.ALC # *********************************************************************************************************** # Get the bounding box of each L1 resolution # *********************************************************************************************************** # list of bounding box per resolution l_L2CoarseBoundingBoxMap = {} # BoundingBoxMapType for res in range(l_NbL1Res): curRes = l_ListOfL1Resolution[res] # string l_IntResolution = l_BandsDefinitions.get_l1_resolution(curRes) l_PointXY = product_info.TileHandler.get_geoposition_upperleftcorner( l_IntResolution) # PointXYType l_L2CoarseBoundingBox = BoundingBox() # ATTENTION: For coordinates, cf. FD 73233 l_L2CoarseBoundingBox.xmin = l_PointXY.x l_L2CoarseBoundingBox.ymin = l_PointXY.y - l_L2CoarseArea.size[ 1] * l_L2CoarseResolution l_L2CoarseBoundingBox.xmax = l_PointXY.x + l_L2CoarseArea.size[ 0] * l_L2CoarseResolution l_L2CoarseBoundingBox.ymax = l_PointXY.y l_L2CoarseBoundingBoxMap[curRes] = l_L2CoarseBoundingBox LOGGER.debug("Start SubSampling ...") # =======> GENERATE TOA SUB IMAGES AT L2 COARSE RESOLUTION self.generate_toa_sub_images(working_dir) LOGGER.debug("Start SubSampling done.") # ******************************************************************************************************* # L2 TOA image pipeline connection # ******************* ************************************************************************************ # =======> GENERATE L2 TOA IMAGES self.generate_l2_toa_images(working_dir) # ******************************************************************************************************* # Rasterize the gml mask per L2 resolution per band # ******************************************************************************************************* # =======> GENERATE MASK RASTERS self.generate_mask_rasters_gml( l_L1BoundingBoxMap, l_Areas, l_ProjectionRef, l_SatPixFileNames, l_DefectivPixFileNames, l_ZoneMaskFileNames, self._plugin. GDAL_RASTERIZE_GML_MASK_ADDITIONAL_COMMAND_LINE_PARAMETERS, self._plugin. GDAL_RASTERIZE_GML_DETECTOR_ADDITIONAL_COMMAND_LINE_PARAMETERS, working_dir) l_CurrentConfigUserCamera = self._plugin.ConfigUserCamera grid_ref_alt = l_CurrentConfigUserCamera.get_Algorithms( ).get_GRID_Reference_Altitudes() l_VIEHRef = grid_ref_alt.get_VIEHRef() # double l_SOLH1 = grid_ref_alt.get_SOLH1() # double # ******************************************************************************************************* # IPSOL Sub image pipeline connection # ******************************************************************************************************* LOGGER.debug("Start IPSOL SubSampling ...") l_solarAngleFile = product_info.TileHandler.angles.sun_angles.write( working_dir) # =======> GENERATE SOLAR ANGLE GRIDS self.get_solar_grids(self._dem.ALC, l_solarAngleFile, l_SOLH1, working_dir) LOGGER.debug("Start IPSOL SubSampling done.") # ******************************************************************************************************* # IPVIE Sub image pipeline connection # ******************************************************************************************************* LOGGER.debug("Start IPVIE SubSampling ...") LOGGER.debug("For each band ...") for l_band in range(l_NbBand): l_L1Resolution = l_BandsDefinitions.get_l1_resolution_for_band_code( l_ListOfTOABandCode[l_band]) # string # Get the list of detectors (index) l_ListOfZone = product_info.TileHandler.get_list_of_zones( l_band) # ListOfUIntegers l_BoundingBox = l_L2CoarseBoundingBoxMap[ l_L1Resolution] # BoundingBoxType # Get the list of viewing angles in the header file of the tile l_vieAngles = product_info.TileHandler.angles.viewing_incidence_angle.get_viewing_angles( l_band) # ListOfListOfStrings if len(l_vieAngles) == 0: raise MajaPluginSentinel2Exception( "No viewing angles for band " + str(l_band)) # =======> GENERATE VIEWING ANGLE GRIDS self.get_viewing_grids( l_band, l_L2CoarseArea, l_ProjectionRef, l_VIEHRef, l_SatPixFileNames[l_band], l_ZoneMaskFileNames[l_band], l_NoDataMaskFileNames[l_band], l_ListOfZone, l_BoundingBox, l_vieAngles, self._plugin. GDAL_RASTERIZE_GML_MASK_ADDITIONAL_COMMAND_LINE_PARAMETERS, self._plugin. GDAL_RASTERIZE_GML_DETECTOR_ADDITIONAL_COMMAND_LINE_PARAMETERS, self._plugin. GDAL_RASTERIZE_GML_NODATA_ADDITIONAL_COMMAND_LINE_PARAMETERS, l_NbBand, working_dir) LOGGER.debug("Start IPVIE SubSampling done.") # To check mean angle values # TODO: TBD # zones = self.m_ViewingZenithMeanMap.keys() # values = zip(zones, # [self.m_ViewingZenithMeanMap.get(zone) for zone in zones], # [self.m_ViewingAzimuthMeanMap.get(zone) for zone in zones]) # for zone, zenith, azimuth in values: # LOGGER.debug(" Mean for zone %s is [zen;azi] : [%s;%s].", zone, zenith, azimuth) # ******************************************************************************************************* # IPEDGSub and L2EDG pipeline connection # ******************************************************************************************************* # ******************************************************************************************************* # IPSAT Sub and L2SAT image pipeline connection # ******************************************************************************************************* # =======> GENERATE SAT IMAGES self.generate_sat_images(working_dir) # ******************************************************************************************************* # CLA image pipeline connection # ******************************************************************************************************* # =======> GENERATE CLA IMAGES self.generate_cla_images(l_RealL1NoData, working_dir) # Fill the datas self.dict_of_vals["IPEDGSubOutput"] = self._edgsubmask self.dict_of_vals["SOL1Image"] = self._sol1image l_DTMBandCode = xml_tools.as_string_list( l2comm.get_value("DTMViewingDirectionBandCode"))[0] l_DTMBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_DTMBandCode) LOGGER.info("DTMBandCode= " + l_DTMBandCode) self.dict_of_vals["DTMVIEImage"] = self._vieimagelist[l_DTMBandIdx] self.dict_of_vals["IPTOASubOutput"] = self._sub_toa self.dict_of_vals["L2TOAImageList"] = self._l2toaimagelist self.dict_of_vals["ViewingZenithMeanMap"] = self._meanZenithMap self.dict_of_vals["ViewingAzimuthMeanMap"] = self._meanAzimuthMap self.dict_of_vals["CLAImage"] = self._claimage self.dict_of_vals["IPSATSubOutput"] = self._subsatimage l_CLDBandCode = l2comm.get_value("CLDViewingDirectionBandCode") l_CLDBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_CLDBandCode) self.dict_of_vals["ShadowVIEImage"] = self._vieimagelist[ l_CLDBandIdx] l_CirrusBandCode = l2comm.get_value("CirrusBandCode") l_CirrusBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_CirrusBandCode) self.dict_of_vals["L1TOACirrusImage"] = self._toa_scalar_list[ l_CirrusBandIdx] self.dict_of_vals["AngleZoneMaskList"] = self._l2zoneimagelist self.dict_of_vals["L2EDGOutputList"] = self._l2edgmasklist self.dict_of_vals["L2SATImageList"] = self._l2satmasklist self.dict_of_vals["L2PIXImageList"] = self._l2piximagelist
def run(self, dict_of_input, dict_of_output): LOGGER.info("AOT estimation computation start") LOGGER.debug("Caching %s", dict_of_input.get("Params").get("Caching")) l_caching = dict_of_input.get("Params").get("Caching") l_writeL2 = dict_of_input.get("Params").get( "WriteL2ProductToL2Resolution") aot_working = dict_of_input.get( "AppHandler").get_directory_manager().get_temporary_directory( "AOTEstimationProc_", do_always_remove=True) init_Mode = dict_of_input.get("Params").get("InitMode") bands_definition = dict_of_input.get("Plugin").BandsDefinitions # TODO concatenate cloud masks param_darkest = { "toac": dict_of_output["AtmoAbsIPTOAC"], "cld": dict_of_output[constants.CLOUD_MASK_ALL], "dtm": dict_of_input.get("DEM").ALC, "edg": dict_of_input.get("L1Reader").get_value("IPEDGSubOutput"), "shd": dict_of_output["dtm_shd"], "lutheader": dict_of_input.get("L2TOCR"), "lutimage": dict_of_output["cr_lut"], "darkestchanneltoac": dict_of_input.get("Params").get("DarkBandIndex_DateD"), "thresholddarkpixel": float(dict_of_input.get("L2SITE").get_value("DarkPixelThreshold")), "darksurfacereflectance": float( dict_of_input.get("L2SITE").get_value( "DarkestPixelSurfaceReflectance")), "darkestchannelrtc": dict_of_input.get("Params").get("DarkBandIndex_DateD") } if not init_Mode: param_darkest["l2ndt"] = dict_of_input.get("L2Reader").get_value( "NDTImage") param_darkest["l2rtc"] = dict_of_input.get("L2Reader").get_value( "RTCImage") else: param_darkest["init"] = init_Mode darkest_app = OtbAppHandler("DarkestPixelAOT", param_darkest, write_output=True) aot_computed = darkest_app.getoutput()["aotcomputed"] darkest_aot = darkest_app.getoutput()["darkestaot"] l_aotmethod = dict_of_input.get("Params").get("AOTMethod") LOGGER.debug("AOT Estimation Computation Method: " + str(l_aotmethod)) #AOT Params xml holder xml_aot_param = AOT_Estimation() #Common parameters xml_aot_param.set_Sampling_Interval_Min( dict_of_input.get("L2COMM").get_value_i("SamplingIntervalMin")) xml_aot_param.set_Sampling_Interval_Max( dict_of_input.get("L2COMM").get_value_i("SamplingIntervalMax")) xml_aot_param.set_Increment_N_Distance( dict_of_input.get("L2COMM").get_value_i("IncrementNDistance")) xml_aot_param.set_Half_Window_Size( dict_of_input.get("L2COMM").get_value_i("HalfWindowSize")) xml_aot_param.set_Max_Iterations( dict_of_input.get("L2COMM").get_value_i("MaxIterations")) xml_aot_param.set_Step_AOT( dict_of_input.get("L2COMM").get_value_i("StepAOT")) xml_aot_param.set_N_Pix_Min( dict_of_input.get("L2COMM").get_value_i("NPixMin")) xml_aot_param.set_F_Tolerance( dict_of_input.get("L2COMM").get_value_f("FTolerance")) xml_aot_param.set_G_Tolerance( dict_of_input.get("L2COMM").get_value_f("GTolerance")) xml_aot_param.set_X_Tolerance( dict_of_input.get("L2COMM").get_value_f("XTolerance")) xml_aot_param.set_Epsilon_Function( dict_of_input.get("L2COMM").get_value_f("EpsilonFunction")) xml_aot_param.set_AOT_initial_D( dict_of_input.get("L2COMM").get_value_f("AOTinitialD")) xml_aot_param.set_W_dark( dict_of_input.get("L2COMM").get_value_f("Wdark")) xml_aot_param.set_W_bounds( dict_of_input.get("L2COMM").get_value_f("Wbounds")) xml_aot_param.set_AOT_min( dict_of_input.get("L2COMM").get_value_f("AOTmin")) xml_aot_param.set_AOT_Max_Age( dict_of_input.get("L2COMM").get_value_f("AOTMaxAge")) xml_aot_param.set_SE_Mask_Dilatation_Radius( dict_of_input.get("L2COMM").get_value_f("SEMaskDilatationRadius")) xml_aot_param.set_SE_Valid_AOT_Radius( dict_of_input.get("L2COMM").get_value_f("SEValidAOTRadius")) aot_image = os.path.join(aot_working, "aot_computed.tif") aot_mask_estimation = os.path.join(aot_working, "aot_mask_computed.tif") param_aot = { "toac": dict_of_output["AtmoAbsIPTOAC"], "sat": dict_of_input.get("L1Reader").get_value("IPSATSubOutput"), "was": dict_of_output["WaterMask"], "dtm": dict_of_input.get("DEM").ALC, "edg": dict_of_input.get("L1Reader").get_value("IPEDGSubOutput"), "shd": dict_of_output["dtm_shd"], "lutheader": dict_of_input.get("L2TOCR"), "lutimage": dict_of_output["cr_lut"], "cld": dict_of_output[constants.CLOUD_MASK_ALL], "reall2nodata": dict_of_input.get("Params").get("RealL2NoData"), "jday": dict_of_input.get("Params").get("JDay"), "darkestaot": darkest_aot, "aotcomputed": aot_image, "aotmask": aot_mask_estimation } if init_Mode: param_aot["init"] = init_Mode if l_aotmethod == AOTEstimation.MULTISPECTRAL: param_aot["mode"] = "multispectral" elif l_aotmethod == AOTEstimation.MULTITEMPORAL: param_aot["mode"] = "multitemporal" elif l_aotmethod == AOTEstimation.SPECTROTEMPORAL: param_aot["mode"] = "spectrotemporal" if l_aotmethod == AOTEstimation.SPECTROTEMPORAL or l_aotmethod == AOTEstimation.MULTITEMPORAL: stdevbandid = bands_definition.get_band_id_in_l2_coarse( dict_of_input.get("L2COMM").get_value("StdevBandCode")) if not init_Mode: param_aot["temporal.lutmap"] = dict_of_input.get( "L2Reader").get_value("LTCImage") param_aot["temporal.altitudemean"] = dict_of_input.get( "DEM").ALT_Mean xml_aot_param.set_Multi_Temporal_Method( Multi_Temporal_MethodType()) xml_aot_param.get_Multi_Temporal_Method().set_First_AOT( dict_of_input.get("L2COMM").get_value_f("FirstAOT")) xml_aot_param.get_Multi_Temporal_Method().set_Second_AOT( dict_of_input.get("L2COMM").get_value_f("SecondAOT")) xml_aot_param.get_Multi_Temporal_Method().set_TOA_Reflectance_Min( dict_of_input.get("L2COMM").get_value_f("TOAReflectanceMin")) xml_aot_param.get_Multi_Temporal_Method().set_TOA_Reflectance_Max( dict_of_input.get("L2COMM").get_value_f("TOAReflectanceMax")) xml_aot_param.get_Multi_Temporal_Method().set_TOA_Reflectance_Step( dict_of_input.get("L2COMM").get_value_f("TOAReflectanceStep")) xml_aot_param.get_Multi_Temporal_Method( ).set_Min_Difference_Thresholds_Calculation( dict_of_input.get("L2COMM").get_value_f( "MinDifferenceThreshold")) xml_aot_param.get_Multi_Temporal_Method().set_Relative_Var_Max( dict_of_input.get("L2COMM").get_value_f("RelativeVarMax")) xml_aot_param.get_Multi_Temporal_Method().set_Var_Band_Code_D( dict_of_input.get("Params").get("VarBandIndex_DateD")) xml_aot_param.get_Multi_Temporal_Method().set_Var_Band_Code_Dm1( dict_of_input.get("Params").get("VarBandIndex_DateDm1")) xml_aot_param.get_Multi_Temporal_Method().set_Stdev_Band_Code( stdevbandid) xml_aot_param.get_Multi_Temporal_Method().set_Std_Noise( dict_of_input.get("L2COMM").get_value_f("StdNoise")) xml_aot_param.get_Multi_Temporal_Method().set_Stdev_Min( dict_of_input.get("L2COMM").get_value_f("StdevMin")) xml_aot_param.get_Multi_Temporal_Method().set_AOT_initial_Dm1( dict_of_input.get("L2COMM").get_value_f("AOTinitialDm1")) xml_aot_param.get_Multi_Temporal_Method().set_W_MT_equation2( dict_of_input.get("L2COMM").get_value_f("WMTequation2")) xml_aot_param.get_Multi_Temporal_Method().set_MT_AOT_Band_Code_D([ str(i) for i in dict_of_input.get("Params").get("MTAOTbandsDateD") ]) xml_aot_param.get_Multi_Temporal_Method( ).set_MT_AOT_Band_Reflectance_Composite_Dm1([ str(i) for i in dict_of_input.get("Params").get( "MTAOTbandsOfTheReflectancesComposite_DateDm1") ]) xml_aot_param.get_Multi_Temporal_Method( ).set_MT_AOT_Band_LUT_Composite_Dm1([ str(i) for i in dict_of_input.get("Params").get( "MTAOTbandsOfTheLTCComposite_DateDm1") ]) if l_aotmethod == AOTEstimation.MULTISPECTRAL or l_aotmethod == AOTEstimation.SPECTROTEMPORAL: lMSAOTRedBand = bands_definition.get_band_id_in_l2_coarse( dict_of_input.get("L2COMM").get_value("MSAOTRedBandCode")) lNDVIAOTBand1 = bands_definition.get_band_id_in_l2_coarse( dict_of_input.get("L2COMM").get_value("NDVIAOTBand1Code")) lNDVIAOTBand2 = bands_definition.get_band_id_in_l2_coarse( dict_of_input.get("L2COMM").get_value("NDVIAOTBand2Code")) l_AOTUsedBandCodes = xml_tools.as_string_list( dict_of_input.get("L2COMM").get_value("MSAOTBandCode")) lMSAOTbands = [ str(bands_definition.get_band_id_in_l2_coarse(f)) for f in l_AOTUsedBandCodes ] xml_aot_param.set_Multi_Spectral_Method( Multi_Spectral_MethodType()) xml_aot_param.get_Multi_Spectral_Method().set_MS_AOT_Band_Code( lMSAOTbands) xml_aot_param.get_Multi_Spectral_Method().set_MS_AOT_Red_Band_Code( lMSAOTRedBand) xml_aot_param.get_Multi_Spectral_Method().set_NDVI_AOT_Band1_Code( lNDVIAOTBand1) xml_aot_param.get_Multi_Spectral_Method().set_NDVI_AOT_Band2_Code( lNDVIAOTBand2) xml_aot_param.get_Multi_Spectral_Method().set_Red_TOA_Threshold( dict_of_input.get("L2COMM").get_value_f("RedTOAThreshold")) xml_aot_param.get_Multi_Spectral_Method().set_NDVI_Threshold( dict_of_input.get("L2COMM").get_value_f("NDVIThreshold")) xml_aot_param.get_Multi_Spectral_Method().set_MS_Slope( dict_of_input.get("L2COMM").get_value_f("MSSlope")) xml_aot_param.get_Multi_Spectral_Method().set_MS_YIntercept( dict_of_input.get("L2COMM").get_value_f("MSYIntercept")) xml_aot_param.get_Multi_Spectral_Method().set_NDVI_Slope( dict_of_input.get("L2COMM").get_value_f("NDVISlope")) xml_aot_param.get_Multi_Spectral_Method().set_NDVI_YIntercept( dict_of_input.get("L2COMM").get_value_f("NDVIYIntercept")) xml_aot_param.get_Multi_Spectral_Method().set_W_MS( dict_of_input.get("L2COMM").get_value_f("WMS")) if l_aotmethod == AOTEstimation.SPECTROTEMPORAL: spectrotemp = Spectro_Temporal_MethodType() xml_aot_param.set_Spectro_Temporal_Method(spectrotemp) xml_aot_param.get_Spectro_Temporal_Method( ).set_MT_Weight_Threshold( dict_of_input.get("L2COMM").get_value_f("MTWeightThreshold")) xml_aot_param.get_Spectro_Temporal_Method().set_A_Coefficient( dict_of_input.get("L2COMM").get_value_f("ACoefficient")) xml_aot_param.get_Spectro_Temporal_Method().set_B_Coefficient( dict_of_input.get("L2COMM").get_value_f("BCoefficient")) const_mask_filename = os.path.join(aot_working, "cloud_constzero.tif") constant_app = constant_image(dict_of_input.get("DEM").ALC, 0, const_mask_filename + ":uint8", write_output=l_caching) constant_mask = constant_app.getoutput()["out"] if dict_of_input.get("Params").get("SnowBandAvailable"): param_aot["snow"] = dict_of_output.get("cld_snow") else: param_aot["snow"] = constant_mask if not init_Mode: param_aot["l2ndt"] = dict_of_input.get("L2Reader").get_value( "NDTImage") param_aot["l2pxd"] = dict_of_input.get("L2Reader").get_value( "PXDImage") param_aot["l2rtc"] = dict_of_input.get("L2Reader").get_value( "RTCImage") param_aot["l2rta"] = dict_of_input.get("L2Reader").get_value( "RTAImage") # Cams related parameters if dict_of_input.get("Params").get("UseCamsData"): xml_aot_param.set_AOT_KPondCAMS( dict_of_input.get("L2COMM").get_value_f("KPondsCams")) xml_aot_param.set_AOT_HeightScale( dict_of_input.get("L2COMM").get_value_f("HeighScale")) param_aot["cams.nodatatau"] = dict_of_input.get("Params").get( "RealL2NoData") param_aot["cams.altmean"] = dict_of_input.get("DEM").ALT_Mean param_aot["cams.aot"] = dict_of_input.get("CAMS_AOT") aot_cams_image = os.path.join(aot_working, "aot_cams.tif") param_aot["aotcams"] = aot_cams_image #Write down the xml interface output = io.StringIO() output.write('<?xml version="1.0" ?>\n') xml_aot_param.export(output, 0, name_='AOTEstimation', namespacedef_='', pretty_print=True) l_xml_param_filename = os.path.join(aot_working, "AOTParams.xml") with open(l_xml_param_filename, "w") as fh: fh.write(output.getvalue().replace(" ", " ")) LOGGER.info("Writed aot params to " + l_xml_param_filename) param_aot["xmlparamsfile"] = l_xml_param_filename # Effectively launch the app aot_app = OtbAppHandler("AOTEstimation", param_aot, write_output=l_caching) if not l_caching: self._aot_pipeline.add_otb_app(aot_app) aot_mean = aot_app.getoutput()["aotmean"] aot_valid = aot_app.getoutput()["aotvalid"] # If cams used then no gapfilling needed if dict_of_input.get("Params").get("UseCamsData"): smoothing_input = aot_app.getoutput()["aotcomputed"] mask_input = aot_app.getoutput()["aotmask"] else: aot_gapfilled_image = os.path.join(aot_working, "aot_gapfilled.tif") aot_gapfilled_mask = os.path.join(aot_working, "aot_gapfilled_mask.tif") param_gapfilling = { "im": aot_app.getoutput()["aotcomputed"], "initwindowsradius": dict_of_input.get("L2COMM").get_value_i("InitWindowRadius"), "maxwindowsradius": dict_of_input.get("L2COMM").get_value_i("MaxWindowRadius"), "reall2nodata": dict_of_input.get("Params").get("RealL2NoData"), "mean": aot_mean, "hasvalidpixels": aot_valid, "defaultvalue": dict_of_input.get("L2COMM").get_value_f("DefaultAOT"), "out": aot_gapfilled_image, "outmask": aot_gapfilled_mask + ":uint8" } gap_filling_app = OtbAppHandler("GapFilling", param_gapfilling, write_output=(l_caching or l_writeL2)) if not (l_caching or l_writeL2): self._aot_pipeline.add_otb_app(gap_filling_app) smoothing_input = gap_filling_app.getoutput()["out"] mask_input = gap_filling_app.getoutput()["outmask"] aot_smoothed_image = os.path.join(aot_working, "aot_smoothed.tif") param_smoothing = { "in": smoothing_input, "out": aot_smoothed_image, "type": "gaussian", "type.gaussian.radius": dict_of_input.get("L2COMM").get_value_f("SigmaSmoothingAOT"), "type.gaussian.maxkernelwidth": 4.0 * dict_of_input.get("L2COMM").get_value_f("SigmaSmoothingAOT"), "type.gaussian.maxerror": 1e-15 } smoothed_app = OtbAppHandler("SmoothingBis", param_smoothing, write_output=l_caching) if (not l_caching): self._aot_pipeline.add_otb_app(smoothed_app) aot_sub_image = os.path.join(aot_working, "aot_sub.tif") param_subresampling = { "dtm": dict_of_input.get("DEM").ALC, "im": smoothed_app.getoutput()["out"], "interp": "linear", "out": aot_sub_image } subresampling_app = OtbAppHandler("Resampling", param_subresampling, write_output=(l_caching or l_writeL2)) if (not (l_caching or l_writeL2)): self._aot_pipeline.add_otb_app(subresampling_app) dict_of_output["AOT_Sub"] = subresampling_app.getoutput()["out"] if l_writeL2: l_nbRes = len(bands_definition.ListOfL2Resolution) aot_list = [] aotmask_list = [] for r in range(0, l_nbRes): l_res = bands_definition.ListOfL2Resolution[r] aot_image = os.path.join(aot_working, "aot_" + l_res + ".tif") aot_mask = os.path.join(aot_working, "aotmask_" + l_res + ".tif") param_subresampling["dtm"] = dict_of_input.get( "DEM").ALTList[r] param_subresampling["im"] = subresampling_app.getoutput( )["out"] param_subresampling["out"] = aot_image resamp_aot_app = OtbAppHandler("Resampling", param_subresampling) dict_of_output["AOT_" + l_res] = resamp_aot_app.getoutput().get("out") param_maskresampling = { "dtm": dict_of_input.get("DEM").ALTList[r], "im": mask_input, "interp": "linear", "out": aot_mask + ":uint8", "threshold": 0.25 } resamp_aotmask_app = OtbAppHandler("Resampling", param_maskresampling) dict_of_output["AOTMASK_" + l_res] = resamp_aotmask_app.getoutput().get( "out") aot_list.append(resamp_aot_app.getoutput().get("out")) aotmask_list.append(resamp_aotmask_app.getoutput().get("out")) dict_of_output["L2AOTList"] = aot_list dict_of_output["L2AOTMaskList"] = aotmask_list
def read(self, product_info, app_handler, l2comm, dem, pReadL1Mode): """product_info,plugin, l2comm,mode :param product_info: L1ImageInformationsBase :param pReadL1Mode: ReadL1ModeType :return: """ LOGGER.info("Start Sentinel2Muscate L1 ImageFileReader ...") product_filename = product_info.HeaderFilename LOGGER.info( "Start Sentinel2Muscate L1 ImageFileReader with filename : " + product_filename) working_dir = app_handler.get_directory_manager( ).get_temporary_directory("L1Read_", do_always_remove=True) self._plugin.initialize(app_handler) self._GIPPL2COMMHandler = l2comm LOGGER.info("Start Sentinel2Muscate L1 ImageFileReader ...") self._ReadL1Mode = pReadL1Mode self._dem = dem # -------------------------------------- # Check the extension of th efile. For Muscate, must be .XML (in upper case) IsValidSatellite = (product_info.HeaderHandler is not None) if not IsValidSatellite: raise MajaExceptionPluginSentinel2Muscate( "The file <{}> is not a valid Sentinel2 L1 product.".format( product_filename)) self.m_headerHandler = product_info.HeaderHandler # Get satellite name self.m_Satellite = product_info.Satellite # -------------------------------------- # Load the header tile file in the xml tile handler to read tile information xmlTileFilename = product_info.xmlTileFilename l_BandsDefinitions = self._plugin.BandsDefinitions # BandsDefinitions # TOA & masks Reader connection l_ListOfTOAImageFileNames = product_info.HeaderHandler.get_list_of_toa_image_filenames( ) l_SatPixFileNames = product_info.HeaderHandler.get_list_of_l1_sat_image_filenames( ) l_DefectivPixFileNames = product_info.HeaderHandler.get_list_of_defective_pixel_image_filenames( ) l_ZoneMaskFileNames = product_info.HeaderHandler.get_map_list_of_detector_footprint_image_filenames( ) l_NoDataMaskFileNames = product_info.HeaderHandler.get_list_of_l1_ndt_image_filenames( ) l_ListOfTOABandCode = product_info.HeaderHandler.get_list_of_band_code( ) # ListOfStrings l_NbBand = len(l_ListOfTOAImageFileNames) # int l_L1NoData = product_info.L1NoData l_ReflectanceQuantificationValue = product_info.ReflectanceQuantification l_RealL1NoData = l_L1NoData * l_ReflectanceQuantificationValue # RealNoDataType if (len(l_ListOfTOABandCode) != len(l_ListOfTOAImageFileNames)) or ( len(l_ListOfTOABandCode) != len(l_SatPixFileNames)) or ( len(l_ListOfTOABandCode) != len(l_DefectivPixFileNames)): raise MajaExceptionPluginSentinel2Muscate( "Sentinel2L1ImageFileReader.CanRead: Internal error: The number of image file, sat file and band code are different !" ) # =======> GENERATE TOA # Get calibration coeffs if activated l_reflectanceMultiplicationValues = [] # ListOfDoubles if xml_tools.as_bool(l2comm.get_value("CalAdjustOption")): l_factors = xml_tools.as_float_list( l2comm.get_value("CalAdjustFactor")) if len(l_factors) != len(l_ListOfTOABandCode): raise MajaDataException( "Not the same number of Calibration coeffs than L1 bands ( {}, {} )" .format(len(l_factors), len(l_ListOfTOABandCode))) for i in range(len(l_ListOfTOABandCode)): l_reflectanceMultiplicationValues.append( l_ReflectanceQuantificationValue * l_factors[i]) else: for i in range(len(l_ListOfTOABandCode)): l_reflectanceMultiplicationValues.append( l_ReflectanceQuantificationValue) l_ProjectionRef = self._dem.ProjRef self.generate_toa(l_ListOfTOAImageFileNames, l_reflectanceMultiplicationValues, working_dir) # string # START READ L1 for ALGORITHMS if pReadL1Mode == ReadL1Mode.READ_L1_MODE_FOR_ALGORITHMS: # =======> GENERATE TOA SUB IMAGES AT L2 COARSE RESOLUTION LOGGER.debug("Start SubSampling ...") self.generate_toa_sub_images(working_dir) LOGGER.debug("Start SubSampling done.") # the gml mask per L2 resolution per band self.generate_mask_rasters(l_SatPixFileNames, l_DefectivPixFileNames, l_ZoneMaskFileNames, l_NoDataMaskFileNames, l_ListOfTOABandCode, working_dir) LOGGER.debug("Filenames Mask Rasters : ") LOGGER.debug(l_SatPixFileNames) LOGGER.debug(l_DefectivPixFileNames) LOGGER.debug(l_ZoneMaskFileNames) LOGGER.debug(l_NoDataMaskFileNames) LOGGER.debug(l_ListOfTOABandCode) # Get the ref altitude l_CurrentConfigUserCamera = self._plugin.ConfigUserCamera grid_ref_alt = l_CurrentConfigUserCamera.get_Algorithms( ).get_GRID_Reference_Altitudes() l_VIEHRef = grid_ref_alt.get_VIEHRef() # double l_SOLH1 = grid_ref_alt.get_SOLH1() # double # IPSOL Sub image pipeline connection LOGGER.debug("Start IPSOL SubSampling ...") sun_angle_col_step = int( product_info.HeaderHandler.get_string_value_of( "SunAngleColStep")) sun_angle_row_step = int( product_info.HeaderHandler.get_string_value_of( "SunAngleRowStep")) # ATTENTION : * -1 for compatibility negative spacing LOGGER.debug( "Angle Resolution Spacing computed in 5000 resolution: " + str(sun_angle_col_step) + " , " + str(sun_angle_row_step)) l_zenithSolarAngles = product_info.HeaderHandler.get_sun_zenithal_angles( ) l_azimuthSolarAngles = product_info.HeaderHandler.get_sun_azimuthal_angles( ) LOGGER.debug("ZenithSolarAngles nb values: " + str(len(l_zenithSolarAngles))) LOGGER.debug("AzimuthSolarAngles nb values: " + str(len(l_azimuthSolarAngles))) l_solarAngleFile = app_handler.get_directory_manager( ).get_temporary_file("sun_angles_") + ".xml" LOGGER.debug("Angles output_filename : %s", l_solarAngleFile) writer = MajaInternalXmlInputAngles(l_zenithSolarAngles, l_azimuthSolarAngles, sun_angle_col_step, sun_angle_row_step, l_solarAngleFile) writer.write() # =======> GENERATE SOLAR ANGLE GRIDS self.get_solar_grids(self._dem.ALC, l_solarAngleFile, l_SOLH1, working_dir) LOGGER.debug("Start IPSOL SubSampling done.") # IPVIE Sub image pipeline connection LOGGER.debug("Start IPVIE SubSampling ...") vie_angle_col_step = int( product_info.HeaderHandler.get_string_value_of( "SunAngleColStep")) vie_angle_row_step = int( product_info.HeaderHandler.get_string_value_of( "SunAngleRowStep")) LOGGER.debug("For each band ...") for l_band in l_ListOfTOABandCode: l1BandIdx = l_BandsDefinitions.get_band_id_in_l1(l_band) # Get the list of detectors (index) l_ListOfZone = product_info.HeaderHandler.get_list_of_zones( l_band) # Get the list of viewing angles in the header file of the tile l_zenithVieAngles = product_info.HeaderHandler.get_viewing_zenithal_angles( l_band) l_azimuthVieAngles = product_info.HeaderHandler.get_viewing_azimuthal_angles( l_band) if len(l_zenithVieAngles) != len(l_azimuthVieAngles): raise MajaExceptionPluginSentinel2Muscate( "The number of detector for viewing zenithal angles and viewing azimuthal angles is different or null !" ) # =======> GENERATE VIEWING ANGLE GRIDS self.GetViewingGrids(l_band, l_NbBand, l_VIEHRef, l_SatPixFileNames[l1BandIdx], l_ZoneMaskFileNames[l1BandIdx], l_NoDataMaskFileNames[l1BandIdx], l_ListOfZone, vie_angle_col_step, vie_angle_row_step, l_zenithVieAngles, l_azimuthVieAngles, working_dir) # end loop nbBand LOGGER.debug("Start IPVIE SubSampling done.") # To check mean angle values # TODO # IPEDGSub and L2EDG pipeline connection # =======> GENERATE EDG IMAGES self.generate_edg_images(working_dir) # L2 TOA image pipeline connection # =======> GENERATE L2 TOA IMAGES self.generate_l2_toa_images(working_dir) # IPSAT Sub and L2SAT image pipeline connection # =======> GENERATE SAT IMAGES self.generate_sat_images(working_dir) # CLA image pipeline connection # =======> GENERATE CLA IMAGES self.generate_cla_images(l_RealL1NoData, working_dir) # Fill the datas self.dict_of_vals["IPEDGSubOutput"] = self._edgsubmask self.dict_of_vals["SOL1Image"] = self._sol1image l_DTMBandCode = xml_tools.as_string_list( l2comm.get_value("DTMViewingDirectionBandCode"))[0] l_DTMBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_DTMBandCode) self.dict_of_vals["DTMVIEImage"] = self._vieimagelist[l_DTMBandIdx] LOGGER.debug("l_DTMBandIdx : ") LOGGER.debug(l_DTMBandIdx) self.dict_of_vals["IPTOASubOutput"] = self._sub_toa self.dict_of_vals["L2TOAImageList"] = self._l2toaimagelist self.dict_of_vals["ViewingZenithMeanMap"] = self._meanZenithMap self.dict_of_vals["ViewingAzimuthMeanMap"] = self._meanAzimuthMap self.dict_of_vals["CLAImage"] = self._claimage self.dict_of_vals["IPSATSubOutput"] = self._subsatimage l_CLDBandCode = l2comm.get_value("CLDViewingDirectionBandCode") l_CLDBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_CLDBandCode) LOGGER.debug("l_CLDBandIdx: ") LOGGER.debug(l_CLDBandIdx) self.dict_of_vals["ShadowVIEImage"] = self._vieimagelist[ l_CLDBandIdx] l_CirrusBandCode = l2comm.get_value("CirrusBandCode") l_CirrusBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_CirrusBandCode) LOGGER.debug("l_CirrusBandIdx: ") LOGGER.debug(l_CirrusBandIdx) self.dict_of_vals["L1TOACirrusImage"] = self._toa_scalar_list[ l_CirrusBandIdx] self.dict_of_vals["AngleZoneMaskList"] = self._l2zoneimagelist self.dict_of_vals["L2EDGOutputList"] = self._l2edgmasklist self.dict_of_vals["L2SATImageList"] = self._l2satmasklist self.dict_of_vals["L2PIXImageList"] = self._l2piximagelist self.dict_of_vals["L2DFPImageList"] = self._l2dfpimagelist
def run(self, dict_of_input, dict_of_output): LOGGER.info("Lut computation start") l_writeL2 = dict_of_input.get("Params").get( "WriteL2ProductToL2Resolution") viewing_zenith = dict_of_input.get( "L1Info").ListOfViewingZenithAnglesPerBandAtL2CoarseResolution viewing_azimuth = dict_of_input.get( "L1Info").ListOfViewingAzimuthAnglesPerBandAtL2CoarseResolution # CR Lut generation rlc_working = dict_of_input.get( "AppHandler").get_directory_manager().get_temporary_directory( "ReduceLutProc_", do_always_remove=True) cr_lut_file = os.path.join(rlc_working, "CR_Lut.mha") param_cr_lut = { "lut": dict_of_input.get("L2TOCR"), "solar.zenith": float(dict_of_input.get("L1Info").SolarAngle["sun_zenith_angle"]), "solar.azimuth": float(dict_of_input.get("L1Info").SolarAngle["sun_azimuth_angle"]), "viewing.zenith": viewing_zenith, "viewing.azimuth": viewing_azimuth, "reducelut": cr_lut_file } if dict_of_input.get( "Plugin").DirectionalCorrection and dict_of_input.get( "L2COMM").get_value("DirCorrOption"): param_cr_lut["coeffsr"] = xml_tools.as_string_list( dict_of_input.get("L2COMM").get_value("CoefsR")) param_cr_lut["coeffsv"] = xml_tools.as_string_list( dict_of_input.get("L2COMM").get_value("CoefsV")) param_cr_lut["refzenith"] = float( dict_of_input.get("L2COMM").get_value("ZenithRef")) param_cr_lut["refazimuth"] = float( dict_of_input.get("L2COMM").get_value("AzimuthRef")) param_cr_lut["dircorr"] = True OtbAppHandler("ReduceLut", param_cr_lut) dict_of_output["cr_lut"] = cr_lut_file # Read the input lut header to get indexes old_lut = maja_xml_app_lut.parse(dict_of_input.get("L2TOCR"), True) # HR lut if wide field l_lutmap = LUTMap() # Add cr lut to map l_listoffile = List_Of_FilesType() l_listoffile.add_Relative_File_Path(os.path.basename(cr_lut_file)) l_lut = LUT(index=0, Indexes=old_lut.get_Indexes(), List_Of_Files=l_listoffile) l_lutmap.add_LUT(l_lut) if dict_of_input.get("Plugin").WideFieldSensor and l_writeL2: m_ViewingZenithAnglesMap = dict_of_input.get("L1Reader").get_value( "ViewingZenithMeanMap") m_ViewingAzimuthAnglesMap = dict_of_input.get( "L1Reader").get_value("ViewingAzimuthMeanMap") for key in list(m_ViewingZenithAnglesMap.keys()): if key not in m_ViewingAzimuthAnglesMap: raise MajaDataException( "Internal ERROR: The Viewing Zenith angles Map per zone are incorrect !!" ) l_listoffile = List_Of_FilesType() l_listoffile.add_Relative_File_Path("HR_Lut_" + key + ".mha") l_lut = LUT(index=key, Indexes=old_lut.get_Indexes(), List_Of_Files=l_listoffile) l_ViewingZenithAngle = m_ViewingZenithAnglesMap.get(key) l_ViewingAzimuthAngle = m_ViewingAzimuthAnglesMap.get(key) if len(l_ViewingZenithAngle) != len( dict_of_input.get( "Plugin").BandsDefinitions.L2CoarseBandMap): raise MajaDataException( "Error on input L1 product: missing Viewing angles for some l2 coarse band on detector " + key + " , all l2 coarse bands are needed for HR_Lut generation" ) hr_lut_file = os.path.join(rlc_working, "HR_Lut_" + key + ".mha") param_hr_lut = { "lut": dict_of_input.get("L2TOCR"), "solar.zenith": float( dict_of_input.get( "L1Info").SolarAngle["sun_zenith_angle"]), "solar.azimuth": float( dict_of_input.get( "L1Info").SolarAngle["sun_azimuth_angle"]), "viewing.zenith": l_ViewingZenithAngle, "viewing.azimuth": l_ViewingAzimuthAngle, "reducelut": hr_lut_file } OtbAppHandler("ReduceLut", param_hr_lut) dict_of_output["hr_lut_" + key] = hr_lut_file l_lutmap.add_LUT(l_lut) # Write down the lut map output = io.StringIO() output.write('<?xml version="1.0" ?>\n') l_lutmap.export(output, 0, name_='LUTMap', namespacedef_='', pretty_print=True) l_lutmap_filename = os.path.join(rlc_working, "HR_LutMap.xml") with open(l_lutmap_filename, "w") as fh: fh.write(output.getvalue().replace(" ", " ")) LOGGER.info("Writed new gipp lutmap to " + l_lutmap_filename) output.close() dict_of_output["hr_lutmap"] = l_lutmap_filename
def read(self, product_info, app_handler, l2comm, dem, pReadL1Mode): """product_info,plugin, l2comm,mode :param product_info: L1ImageInformationsBase :param pReadL1Mode: ReadL1ModeType :return: """ LOGGER.info("Start Muscate L1 ImageFileReader ...") product_filename = product_info.HeaderFilename LOGGER.info("Start Muscate L1 ImageFileReader with filename : " + product_filename) working_dir = app_handler.get_directory_manager( ).get_temporary_directory("L1Read_", do_always_remove=True) self._plugin.initialize(app_handler) self._GIPPL2COMMHandler = l2comm LOGGER.info("Start Muscate L1 ImageFileReader ...") self._ReadL1Mode = pReadL1Mode self._dem = dem self._header_handler = product_info.HeaderHandler # -------------------------------------- # Check the extension of th efile. For Muscate, must be .XML (in upper case) IsValidSatellite = (self._header_handler is not None) if not IsValidSatellite: raise MajaExceptionPluginMuscate( "The file <{}> is not a valid Muscate L1 product.".format( product_filename)) # Get satellite name self.m_Satellite = product_info.Satellite # -------------------------------------- # Load the header tile file in the xml tile handler to read tile information xmlTileFilename = product_info.xmlTileFilename l_BandsDefinitions = self._plugin.BandsDefinitions # BandsDefinitions # TOA & masks Reader connection l_ListOfTOAImageFileNamesInHeader = self._header_handler.get_list_of_toa_image_filenames( ) l_ListOfTOAImageFileNames = [] l_ListOfTOABandCode = l_BandsDefinitions.get_list_of_band_code_in_l2_coarse_sorted_by_index( ) # ListOfStrings for band in l_ListOfTOABandCode: LOGGER.debug(band) l_ListOfTOAImageFileNames.append(l_ListOfTOAImageFileNamesInHeader[ self._header_handler.get_index_of_band_code(band)]) l_ListOfL1Resolution = l_BandsDefinitions.ListOfL1Resolution # ListOfStrings l_ListOfL2Resolution = l_BandsDefinitions.ListOfL2Resolution # ListOfStrings l_L1NoData = product_info.L1NoData l_ReflectanceQuantificationValue = product_info.ReflectanceQuantification l_RealL1NoData = l_L1NoData * l_ReflectanceQuantificationValue # RealNoDataType # =======> GENERATE TOA # Get calibration coeffs if activated l_reflectanceMultiplicationValues = [] # ListOfDoubles if xml_tools.as_bool(l2comm.get_value("CalAdjustOption")): l_factors = xml_tools.as_float_list( l2comm.get_value("CalAdjustFactor")) if len(l_factors) != len(l_ListOfTOABandCode): raise MajaDataException( "Not the same number of Calibration coeffs than L1 bands ( {}, {} )" .format(len(l_factors), len(l_ListOfTOABandCode))) for i in range(len(l_ListOfTOABandCode)): l_reflectanceMultiplicationValues.append( l_ReflectanceQuantificationValue * l_factors[i]) else: for i in range(len(l_ListOfTOABandCode)): l_reflectanceMultiplicationValues.append( l_ReflectanceQuantificationValue) l_ProjectionRef = self._dem.ProjRef self.generate_toa(l_ListOfTOAImageFileNames, l_reflectanceMultiplicationValues, working_dir) # string if pReadL1Mode == ReadL1Mode.READ_L1_MODE_FOR_ALGORITHMS: # -------------------------------------- # Get information of areas (footprint) of the product (Origin, Spacing and Size for L2 and L2Coarse resolution) l_L2Dems = dem.ALTList l_CoarseDem = dem.ALC # =======> GENERATE TOA SUB IMAGES AT L2 COARSE RESOLUTION LOGGER.debug("Start SubSampling ...") self.generate_toa_sub_images(working_dir) LOGGER.debug("Start SubSampling done.") # the gml mask per L2 resolution per band self.generate_mask_rasters(l_ListOfTOABandCode, working_dir) # IPEDGSub and L2EDG pipeline connection # L2 TOA image pipeline connection # =======> GENERATE L2 TOA IMAGES self.generate_l2_toa_images(working_dir) # =======> GENERATE L1 TOA IMAGES self.generate_l1_toa_images(working_dir) # =======> GENERATE EDG IMAGES self.generate_edg_images(working_dir) # IPSAT Sub and L2SAT image pipeline connection # =======> GENERATE SAT IMAGES self.generate_sat_images(working_dir) # CLA image pipeline connection # ********************************************************************************************************* self.generate_cla_image(l_RealL1NoData, working_dir) # SOL1 image pipeline connection # ********************************************************************************************************* sol_h1 = self._plugin.ConfigUserCamera.get_Algorithms( ).get_GRID_Reference_Altitudes().get_SOLH1() LOGGER.debug("sol_H1 : ") LOGGER.debug(sol_h1) self.generate_sol1_image(sol_h1, working_dir) # SOL2 image pipeline connection # ********************************************************************************************************* if self._plugin.GRIDReferenceAltitudesSOL2GridAvailable: sol_h2 = self._plugin.ConfigUserCamera.get_Algorithms( ).get_GRID_Reference_Altitudes().get_SOLH2() self.generate_sol2_image(sol_h2, working_dir) # VIE image pipeline connection # ********************************************************************************************************* vie_href = self._plugin.ConfigUserCamera.get_Algorithms( ).get_GRID_Reference_Altitudes().get_VIEHRef() self.generate_vie_image(vie_href, working_dir) # Fill the datas self.dict_of_vals["IPEDGSubOutput"] = self._edgsubmask self.dict_of_vals["SOL1Image"] = self._sol1image self.dict_of_vals["SOL2Image"] = self._sol2image if len(self._vieimagelist) > 2: l_DTMBandCode = xml_tools.as_string_list( l2comm.get_value("DTMViewingDirectionBandCode"))[0] l_DTMBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_DTMBandCode) LOGGER.info("DTMBandCode= " + l_DTMBandCode) self.dict_of_vals["DTMVIEImage"] = self._vieimagelist[ l_DTMBandIdx] else: self.dict_of_vals["DTMVIEImage"] = self._vieimagelist[0] self.dict_of_vals["IPTOASubOutput"] = self._sub_toa self.dict_of_vals["L2TOAImageList"] = self._l2toaimagelist self.dict_of_vals["ViewingZenithMeanMap"] = self._meanZenithMap self.dict_of_vals["ViewingAzimuthMeanMap"] = self._meanAzimuthMap self.dict_of_vals["CLAImage"] = self._claimage self.dict_of_vals["IPSATSubOutput"] = self._subsatimage if len(self._vieimagelist) > 2: l_CLDBandCode = l2comm.get_value("CLDViewingDirectionBandCode") l_CLDBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_CLDBandCode) self.dict_of_vals["ShadowVIEImage"] = self._vieimagelist[ l_CLDBandIdx] elif len(self._vieimagelist) > 1: self.dict_of_vals["ShadowVIEImage"] = self._vieimagelist[1] else: self.dict_of_vals["ShadowVIEImage"] = self._vieimagelist[0] if self._plugin.CirrusMasking: l_CirrusBandCode = l2comm.get_value("CirrusBandCode") l_CirrusBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse( l_CirrusBandCode) self.dict_of_vals["L1TOACirrusImage"] = self._toa_scalar_list[ l_CirrusBandIdx] self.dict_of_vals["L2EDGOutputList"] = self._l2edgmasklist self.dict_of_vals["L2SATImageList"] = self._l2satmasklist self.dict_of_vals["L2PIXImageList"] = self._l2dfpimagelist