def write_private_sto_xmlhandler(self, sto_header_filename, p_ReferenceProductHeaderId,
                                  p_ReferenceProductInstance, p_dem, p_Validity_Start,
                                  p_Validity_Stop, p_Mission, p_root_template_directory,
                                  p_SchemaLocationDirectory, pCurrentDate,
                                  p_EnableCheckXMLFilesWithSchema=True):
        l_CoarseProductImageSizeX = p_dem.CoarseArea.size[0]
        l_CoarseProductImageSizeY = p_dem.CoarseArea.size[1]

        resol = 0
        l_DL2L2CoarseRatio = float(p_dem.L2Areas[resol].size[0]) / float(p_dem.CoarseArea.size[0])
        l_L2L2CoarseRatio = int(l_DL2L2CoarseRatio + 0.5)

        # ---------------------------------------------------------------------------------------------------
        # Date PDV in UTC format
        # Get Validity
        lCreator_Version = self.plugin.Creator_Version
        lFile_Version = self.plugin.L2PRODUCT_FILE_VERSION
        lReferenceProductHeaderId = p_ReferenceProductHeaderId
        lReferenceProductInstance = p_ReferenceProductInstance
        # ---------------------------------------------------------------------------------------------------
        # Write STO
        LOGGER.debug("Write the PRIVATE STO header file ...")
        output_filename = sto_header_filename  # p_L2PrivateImageFilenamesProvider.GetSTOHeaderFileName()
        current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTANX_PRIVATE_STO_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaPluginBaseException(
                "Internal error: the template file '" +
                current_header_filename +
                "' doesn't exist !!")
        # ---------------------------------------------------------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version, output_filename, self.creator,
                              lCreator_Version,
                              self.notes, self.system, self.outputfileclass, pCurrentDate,
                              lReferenceProductHeaderId)
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX, l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)
        # Update other parameter
        output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
        output_handler.set_string_value("//Subsampling_Factor/By_Line", l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column", l_L2L2CoarseRatio)

        output_handler.set_string_value("//Size/Bands", self.numberofstackimages)
        output_handler.set_list_of_bands(self.stolistofstringdates)  # , "//List_of_Bands", "Band")
        # The Band_Theoretical_Wavelength could be not exist (ex: VENUS)
        # Check the existance of the Node in the template xml file, before write the value
        if xml_tools.get_only_value(output_handler.root, "//Band_Theoretical_Wavelength", check=True) is not None:
            output_handler.set_string_value(
                "//Band_Theoretical_Wavelength",
                self.correlbandtheoreticalwavelengthforstocomposite)
        # Save to file
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
Exemplo n.º 2
0
 def __init__(self, main_xml_file, validate=False, schema_path=None):
     """
     Constructor
     """
     LOGGER.info("Loading " + main_xml_file)
     self.main_xml_file = main_xml_file
     self.root = xml_tools.get_root_xml(self.main_xml_file, deannotate=True)
     if validate and schema_path is not None:
         xml_tools.check_xml(main_xml_file, schema_path)
 def write_private_tec_xmlhandler(self,
                                  tec_header_filename,
                                  p_ReferenceProductHeaderId,
                                  p_Validity_Start,
                                  p_Validity_Stop,
                                  p_Mission,
                                  p_NickName,
                                  p_AcquisitionDate,
                                  p_root_template_directory,
                                  p_SchemaLocationDirectory,
                                  pCurrentDate,
                                  p_EnableCheckXMLFilesWithSchema=True):
     # ---------------------------------------------------------------------------------------------------
     # Date PDV in UTC format
     # Get Validity
     lCreator_Version = self.plugin.Creator_Version
     lFile_Version = self.plugin.L2PRODUCT_FILE_VERSION
     lReferenceProductHeaderId = p_ReferenceProductHeaderId
     l_TECFileType = "TEC_L2VALD"
     # ---------------------------------------------------------------------------------------------------
     if not self.productisvalid:
         l_TECFileType = "TEC_L2NOTV"
     # ---------------------------------------------------------------------------------------------------
     # Write TEC Private EEF
     LOGGER.debug("Write the PRIVATE TEC header file ...")
     output_filename = tec_header_filename  # p_L2ImageFilenamesProvider->GetPrivateFileNames().GetHDRPrivateFileName()
     current_header_filename = os.path.join(
         p_root_template_directory, self.plugin.TEMPLATE_TEC_PRIVATE_EEF)
     if not os.path.exists(current_header_filename):
         raise MajaExceptionPluginBase(
             "Internal error: the template file '" +
             current_header_filename + "' doesn't exist !!")
     # ---------------------------------------------------------------------------------------------
     # Load the template file used to writes the new header file
     # Load the file
     output_handler = EarthExplorerXMLFileHandler(current_header_filename)
     # ---------------------------------------------------------------------------------------------
     # Update bascis parameters
     output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                           output_filename, self.creator, lCreator_Version,
                           self.notes, self.system, self.outputfileclass,
                           pCurrentDate, lReferenceProductHeaderId)
     # Update other parameters
     output_handler.set_string_value("//Mission", p_Mission)
     # File_Type
     output_handler.set_string_value("//File_Type", l_TECFileType)
     # Nick_Name
     output_handler.set_string_value("//Nick_Name", p_NickName)
     # Acquisition_Date
     output_handler.set_string_value("//Acquisition_Date",
                                     p_AcquisitionDate)
     # Save to file
     output_handler.save_to_file(output_filename)
     LOGGER.debug(p_EnableCheckXMLFilesWithSchema)
     if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
         xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
Exemplo n.º 4
0
    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 write_private_ltc_xmlhandler(self,
                                     p_InputL2ImageFileReader,
                                     p_ReferenceProductHeaderId,
                                     p_ReferenceProductInstance,
                                     root_sc_xml_templates,
                                     p_OutputL2PrivateImageFilenamesProvider,
                                     schemaLocationDirectory,
                                     pCurrentDate,
                                     pValidity_Start,
                                     pValidity_Stop,
                                     p_MeanSolarAngles,
                                     p_MeanViewingAngles,
                                     p_EnableCheckXMLFilesWithSchema=True):
        output_filename = p_OutputL2PrivateImageFilenamesProvider.get_ltc_header_filename(
        )
        l_FileDefinition = self.plugin.ShortFileType + "_LUTANX"
        # ---------------------------------------
        # Get global information about the output L2 product
        # ---------------------------------------
        LOGGER.debug("Write the PRIVATE LTC header file ...")
        lReferenceProductHeaderId = p_ReferenceProductHeaderId
        lReferenceProductInstance = p_ReferenceProductInstance
        lFile_Version = self.plugin.L2PRODUCT_FILE_VERSION
        # Get Validity
        lValidity_Start = pValidity_Start
        lValidity_Stop = pValidity_Stop

        current_header_filename = root_sc_xml_templates
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")

        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(pValidity_Start, pValidity_Stop, lFile_Version,
                              output_filename, self.creator,
                              self.plugin.Creator_Version, self.notes,
                              self.system, self.outputfileclass, pCurrentDate,
                              lReferenceProductHeaderId)
        # ---------------------------------------
        # Detect the good GIPP TOCR filename to read data
        # ---------------------------------------
        lNbGippFilenames = len(self.listofgippsfilenames)
        l_found = False
        l_GIPTOCRFilename = ""
        # For each GIPP filename of the list
        for i in range(lNbGippFilenames):
            # Look for the header file of the GIP_L2TOCR
            l_FileName = self.listofgippsfilenames[i]
            l_FileName = os.path.splitext(l_FileName)[0] + ".HDR"
            # ---------------------------------------------------------------------------------------------------
            # Load the file
            l_CanLoad = xml_tools.can_load_file(l_FileName)
            if l_CanLoad:
                # Read the header file of the GIP_L2TOCR
                lHolder = EarthExplorerXMLFileHandler(l_FileName)
                l_Satellite = lHolder.get_string_value("//Mission")
                l_File_Type = lHolder.get_string_value("//File_Type")
                # Check the validity of the found GIPP : camera and type
                if l_Satellite in self.l1imageinformationsproviderbase.Satellite and "GIP_L2TOCR" in l_File_Type:
                    l_GIPTOCRFilename = l_FileName
                    l_found = True

        # The GIP_L2TOCR does not exist
        if not l_found:
            raise MajaExceptionPluginBase(
                "Impossible to detect the TOCR GIPP filename for the current satellite <"
                + self.l1imageinformationsproviderbase.Satellite + "> !")

        # ****************************************************************************************
        # Write LUT_Indexes information
        lTOCRHolder = EarthExplorerXMLFileHandler(l_GIPTOCRFilename)
        # ---------------------------------------------------------------------------------------------------
        # Get the information of the input LUT to copy them in the LTC header file
        output_handler.set_string_value(
            "//LUT_Indexes/Altitude_Indexes",
            lTOCRHolder.get_string_value("//LUT_Indexes/Altitude_Indexes"))
        output_handler.set_string_value(
            "//LUT_Indexes/AOT_Indexes",
            lTOCRHolder.get_string_value("//LUT_Indexes/AOT_Indexes"))
        output_handler.set_string_value(
            "//LUT_Indexes/TOA_Reflectance_Indexes",
            lTOCRHolder.get_string_value(
                "//LUT_Indexes/TOA_Reflectance_Indexes"))
        output_handler.set_string_value(
            "//Mission", self.l1imageinformationsproviderbase.Satellite)
        output_handler.set_string_value("//Reference_Product_Instance",
                                        lReferenceProductInstance)
        l_attr = dict()
        l_attr["unit"] = "nanometer"
        xml_tools.set_string_list_value_sorted_by_attribute(
            output_handler.root,
            self.listofbandtheoreticalwavelengthforltccomposite,
            "//List_of_Band_Theoretical_Wavelength",
            "Band_Theoretical_Wavelength", "count", "sn", 1, l_attr)

        #                    output_handler.save_to_fileAndCheck(output_filename, lSchemaLocationDirectory)
        # ---------------------------------------
        # Check the product validity of the output L2 product
        # ---------------------------------------
        if self.productisvalid:
            output_handler.set_string_value("//Reference_Product_Semantic",
                                            "L2VALD")
        else:
            output_handler.set_string_value("//Reference_Product_Semantic",
                                            "L2NOTV")
        # Initialization used to write the binary data of the LTC file
        listOfLTC = []
        listOfpft = []
        LOGGER.debug(
            "p_OutputL2PrivateImageFilenamesProvider.GetLTCHeaderFileName(): "
            +
            p_OutputL2PrivateImageFilenamesProvider.get_ltc_header_filename())

        # 4.3         l_DestinationDir = Utilities::SetExtension(output_filename, ".DBL.DIR")
        l_DestinationDir = p_OutputL2PrivateImageFilenamesProvider.get_ltc_image_dir_filename(
        )
        LOGGER.debug("l_DestinationDir: " + l_DestinationDir)
        l_DestinationRelativeDir = os.path.basename(l_DestinationDir)
        LOGGER.debug("l_DestinationRelativeDir: " + l_DestinationRelativeDir)
        # ****************************************************************************************
        # Reading Angles Solar and Viewing from LTC of L2 previous product
        if not self.initmode:
            if p_InputL2ImageFileReader is None:
                raise MajaExceptionPluginBase(
                    "Internal error: the variable m_InputL2ImageFileReader is NULL!"
                )
            # p_L2PrivateImageFilenamesProvider.GetLTCHeaderFileName()
            # #m_L2InputImageFilenamesProvider->GetPrivateFileNames().GetLTCHeaderFileName()
            L2_LTCHeaderFilename = p_InputL2ImageFileReader.L2PrivateImageFilenamesProvider.get_ltc_header_filename(
            )
            LOGGER.debug(
                "Nominal mode: open the L2 input LTC HeaderFileName: " +
                L2_LTCHeaderFilename)
            lHolder = EarthExplorerXMLFileHandler(L2_LTCHeaderFilename)
            lHolder.get_l2_product_ltc_information(l_DestinationRelativeDir,
                                                   listOfLTC, listOfpft)
            # Copy all files from the L2 Input directory to the output L2 product
            file_utils.copy_tree(
                p_InputL2ImageFileReader.L2PrivateImageFilenamesProvider.
                get_ltc_image_dir_filename(), l_DestinationDir)
        # ****************************************************************************************
        # Reading Solar and Viewing angles from L1 product
        # Push in the list
        LOGGER.debug("m_IgnoreCurrentLTC: " + str(self.ignorecurrentltc))
        if not self.ignorecurrentltc:
            ltc = EarthExplorerXMLFileHandler.LTCType()
            solarAngles = p_MeanSolarAngles
            #[p_MeanSolarAngles['sun_zenith_angle'], p_MeanSolarAngles['sun_azimuth_angle']]
            LOGGER.debug(solarAngles)
            LOGGER.debug(
                EarthExplorerXMLFileHandler.EE_SCHEMA_DECIMAL_9_FORMAT)
            ltc.solarangle.azimuth = maja_utils.format_to_string(
                float(solarAngles[1]),
                EarthExplorerXMLFileHandler.EE_SCHEMA_DECIMAL_9_FORMAT)
            ltc.solarangle.zenith = maja_utils.format_to_string(
                float(solarAngles[0]),
                EarthExplorerXMLFileHandler.EE_SCHEMA_DECIMAL_9_FORMAT)
            viewingAngles = p_MeanViewingAngles
            ltc.viewingangle.azimuth = maja_utils.format_to_string(
                viewingAngles[1],
                EarthExplorerXMLFileHandler.EE_SCHEMA_DECIMAL_9_FORMAT)
            ltc.viewingangle.zenith = maja_utils.format_to_string(
                viewingAngles[0],
                EarthExplorerXMLFileHandler.EE_SCHEMA_DECIMAL_9_FORMAT)
            ltc.Date = lValidity_Start
            # Add the current LTC header
            pft = EarthExplorerXMLFileHandler.PackagedDBLFileType()
            pft.relativefilepath = os.path.join(
                l_DestinationRelativeDir,
                os.path.basename(p_OutputL2PrivateImageFilenamesProvider.
                                 get_ltc_image_filename()))
            pft.filedefinition = l_FileDefinition
            listOfpft.append(pft)
            listOfLTC.append(ltc)
        # Write to the output handler
        output_handler.write_private_ltc_header(listOfLTC)
        output_handler.write_private_ltc_header_list_of_dbl(listOfpft)
        # ****************************************************************************************
        # Save the file
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, schemaLocationDirectory)
        # ****************************************************************************************
        # Post processing : to be sur that there are only mha listed in the listOfpft present in the directory, remove others files
        # LAIG-FA-MAC-1630-CNES
        # ---------------------------------------------------------------------------------------
        # Get the Listed filename
        l_LTCProductMHAFilename = list()
        for itList in listOfpft:
            # Get file but onlyt the mha (without l_DestinationRelativeDir)
            # Ex :
            # <Relative_File_Path>VE_TEST_VSC_LUTANX_L2VALD_CAMARGUE_20120101_LTC.DBL.DIR/VE_TEST_VSC_LUTANX_L2VALD_CAMARGUE_20120103_LTC.DBL.mha</Relative_File_Path>
            l_LTCProductMHAFilename.append(
                os.path.basename(itList.relativefilepath))
        # ---------------------------------------------------------------------------------------
        # Get the Listed filename in the directory
        l_LTCProductMHAFilenameInDisc = [
            os.path.basename(f) for f in os.listdir(l_DestinationDir)
            if os.path.isfile(os.path.join(l_DestinationDir, f))
        ]

        # Remove the files on disc that are not listed as used
        for f in l_LTCProductMHAFilenameInDisc:
            if f not in l_LTCProductMHAFilename:
                file_utils.remove_file(os.path.join(l_DestinationDir, f))
    def write_private_others_xmlhandler(self,
                                        p_L2PrivateImageFilenamesProvider,
                                        p_ReferenceProductHeaderId,
                                        p_ReferenceProductInstance,
                                        p_dem,
                                        p_Validity_Start,
                                        p_Validity_Stop,
                                        p_Mission,
                                        p_root_template_directory,
                                        p_SchemaLocationDirectory,
                                        pCurrentDate,
                                        p_EnableCheckXMLFilesWithSchema=True):
        LOGGER.debug("L2HeaderWriterBase __dict__ %s", self.__dict__)
        l_CoarseProductImageSizeX = p_dem.CoarseArea.size[0]
        l_CoarseProductImageSizeY = p_dem.CoarseArea.size[1]
        resol = 0
        l_DL2L2CoarseRatio = float(p_dem.L2Areas[resol].size[0]) / float(
            p_dem.CoarseArea.size[0])
        l_L2L2CoarseRatio = int(l_DL2L2CoarseRatio + 0.5)
        LOGGER.debug("Real L2L2CoarseRatio: " + str(l_DL2L2CoarseRatio) +
                     " -> integer: " + str(l_L2L2CoarseRatio))
        # ---------------------------------------------------------------------------------------------------
        # Date PDV in UTC format
        # Get Validity
        lCreator_Version = self.plugin.Creator_Version
        lFile_Version = self.plugin.L2PRODUCT_FILE_VERSION
        lReferenceProductHeaderId = p_ReferenceProductHeaderId
        lReferenceProductInstance = p_ReferenceProductInstance
        # ---------------------------------------------------------------------------------------------------
        # Write CLD
        output_filename = p_L2PrivateImageFilenamesProvider.get_cld_header_filename(
        )
        LOGGER.debug("Write the PRIVATE CLD header file " + output_filename +
                     " ...")
        current_header_filename = os.path.join(
            p_root_template_directory,
            self.plugin.TEMPLATE_PDTANX_PRIVATE_CLD_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")

        LOGGER.debug("LoadFile '" + current_header_filename + "...")
        # ---------------------------------------------------------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                              output_filename, self.creator, lCreator_Version,
                              self.notes, self.system, self.outputfileclass,
                              pCurrentDate, lReferenceProductHeaderId)
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                     l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)
        # Update other parameter
        output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                        l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                        l_L2L2CoarseRatio)
        l_CLDNbBits = self.plugin.NumbersOfBitsInCLDDataIOBand
        output_handler.set_string_value("//Number_of_Significant_Bits",
                                        l_CLDNbBits)
        if l_CLDNbBits <= 8:
            output_handler.set_string_value("//Data_Type", "UNSIGNED_BYTE")
        elif l_CLDNbBits <= 16:
            output_handler.set_string_value("//Data_Type", "UNSIGNED_SHORT")
        else:
            raise MajaExceptionPluginBase(
                "Internal error:  CLD band must be written with [1..16] bits !"
            )
        # save file
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
        # ---------------------------------------------------------------------------------------------------
        # Write NDT
        LOGGER.debug("Write the PRIVATE NDT header file ...")
        output_filename = p_L2PrivateImageFilenamesProvider.get_ndt_header_filename(
        )
        current_header_filename = os.path.join(
            p_root_template_directory,
            self.plugin.TEMPLATE_PDTANX_PRIVATE_NDT_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")
        # ---------------------------------------------------------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                              output_filename, self.creator, lCreator_Version,
                              self.notes, self.system, self.outputfileclass,
                              pCurrentDate, lReferenceProductHeaderId)
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                     l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)
        # Update other parameter
        output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                        l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                        l_L2L2CoarseRatio)
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
        # ---------------------------------------------------------------------------------------------------
        # Write WAM
        LOGGER.debug("Write the PRIVATE WAM header file ...")
        output_filename = p_L2PrivateImageFilenamesProvider.get_wam_header_filename(
        )
        current_header_filename = os.path.join(
            p_root_template_directory,
            self.plugin.TEMPLATE_PDTANX_PRIVATE_WAM_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")
        # -----------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                              output_filename, self.creator, lCreator_Version,
                              self.notes, self.system, self.outputfileclass,
                              pCurrentDate, lReferenceProductHeaderId)
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                     l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)
        # Update other parameter
        output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                        l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                        l_L2L2CoarseRatio)
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
        # ---------------------------------------------------------------------------------------------------
        # Write CLA
        # LAIG-DM-MAC-1691-CNES : Write CLA only is available (only for VENUS - stereo)
        if os.path.exists(
                p_L2PrivateImageFilenamesProvider.get_cla_image_filename()):
            LOGGER.debug("Write the PRIVATE CLA header file ...")
            output_filename = p_L2PrivateImageFilenamesProvider.get_cla_header_filename(
            )

            current_header_filename = os.path.join(
                p_root_template_directory,
                self.plugin.TEMPLATE_PDTANX_PRIVATE_CLA_HDR)
            if not os.path.exists(current_header_filename):
                raise MajaExceptionPluginBase(
                    "Internal error: the template file '" +
                    current_header_filename + "' doesn't exist !!")
            # ---------------------------------------------------------------------------------------------------
            # Load the file
            output_handler = EarthExplorerXMLFileHandler(
                current_header_filename)
            # ---------------------------------------------------------------------------------------------
            # Update bascis parameters
            output_handler.update(p_Validity_Start, p_Validity_Stop,
                                  lFile_Version, output_filename, self.creator,
                                  lCreator_Version, self.notes, self.system,
                                  self.outputfileclass, pCurrentDate,
                                  lReferenceProductHeaderId)
            # ---------------------------------------------------------------------------------------------
            # Update bascis ANX parameters
            output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                         l_CoarseProductImageSizeY,
                                         lReferenceProductInstance,
                                         self.productisvalid)
            # Update other parameter
            output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
            output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                            l_L2L2CoarseRatio)
            output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                            l_L2L2CoarseRatio)
            output_handler.save_to_file(output_filename)
            if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
                xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
        # ---------------------------------------------------------------------------------------------------
        # Write PXD
        LOGGER.debug("Write the PRIVATE PXD header file ...")
        output_filename = p_L2PrivateImageFilenamesProvider.get_pxd_header_filename(
        )
        current_header_filename = os.path.join(
            p_root_template_directory,
            self.plugin.TEMPLATE_PDTANX_PRIVATE_PXD_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")
        # ---------------------------------------------------------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                              output_filename, self.creator, lCreator_Version,
                              self.notes, self.system, self.outputfileclass,
                              pCurrentDate, lReferenceProductHeaderId)
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                     l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)
        # Update other parameter
        output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
        output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                        l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                        l_L2L2CoarseRatio)
        # Save to file
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
    def write_private_reflectances_xmlhandler(
            self,
            p_L2PrivateImageFilenamesProvider,
            p_ReferenceProductHeaderId,
            p_ReferenceProductInstance,
            p_dem,
            p_Validity_Start,
            p_Validity_Stop,
            p_Mission,
            p_root_template_directory,
            p_SchemaLocationDirectory,
            pCurrentDate,
            p_EnableCheckXMLFilesWithSchema=True):
        # ---------------------------------------------------------------------------------------------------
        l_CoarseProductImageSizeX = p_dem.CoarseArea.size[0]
        l_CoarseProductImageSizeY = p_dem.CoarseArea.size[1]
        resol = 0
        l_DL2L2CoarseRatio = float(p_dem.L2Areas[resol].size[0]) / float(
            p_dem.CoarseArea.size[0])
        l_L2L2CoarseRatio = int(l_DL2L2CoarseRatio + 0.5)
        LOGGER.debug("Real L2L2CoarseRatio: " + str(l_DL2L2CoarseRatio) +
                     " -> integer: " + str(l_L2L2CoarseRatio))
        # ---------------------------------------------------------------------------------------------------
        # Date PDV in UTC format
        # Get Validity
        lCreator_Version = self.plugin.Creator_Version
        lFile_Version = self.plugin.L2PRODUCT_FILE_VERSION

        lReferenceProductHeaderId = str(p_ReferenceProductHeaderId)
        lReferenceProductInstance = str(p_ReferenceProductInstance)

        # ---------------------------------------------------------------------------------------------------
        # Write RCR
        LOGGER.debug("Write the PRIVATE RCR header file ...")
        output_filename = p_L2PrivateImageFilenamesProvider.get_rcr_header_filename(
        )
        current_header_filename = os.path.join(
            p_root_template_directory,
            self.plugin.TEMPLATE_PDTANX_PRIVATE_RCR_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")
        # ---------------------------------------------------------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                              output_filename, self.creator, lCreator_Version,
                              self.notes, self.system, self.outputfileclass,
                              pCurrentDate, lReferenceProductHeaderId)
        # Attribut for theoretical wavelength
        l_attr = {}
        l_attr["unit"] = "nanometer"
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                     l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)
        output_handler.set_string_value("//Annex_Code", "RCR")
        output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
        output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                        l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                        l_L2L2CoarseRatio)
        #        output_handler->SetUIntegersListValueSortedByAttribut(m_ListOfBandTheoreticalWavelengthForReflectancesComposite,
        #                "//List_of_Band_Theoretical_Wavelength", "Band_Theoretical_Wavelength", "count", "sn", l_attr)
        xml_tools.set_string_list_value_sorted_by_attribute(
            output_handler.root,
            self.listofbandtheoreticalwavelengthforreflectancescomposite,
            "//List_of_Band_Theoretical_Wavelength",
            "Band_Theoretical_Wavelength", "count", "sn", 1, l_attr)
        output_handler.set_string_value(
            "//Bands",
            str(
                len(self.
                    listofbandtheoreticalwavelengthforreflectancescomposite)))
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
        # ---------------------------------------------------------------------------------------------------
        # Write RTA
        LOGGER.debug("Write the PRIVATE RTA header file ...")
        output_filename = p_L2PrivateImageFilenamesProvider.get_rta_header_filename(
        )
        current_header_filename = os.path.join(
            p_root_template_directory,
            self.plugin.TEMPLATE_PDTANX_PRIVATE_RCR_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")
        # ---------------------------------------------------------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                              output_filename, self.creator, lCreator_Version,
                              self.notes, self.system, self.outputfileclass,
                              pCurrentDate, lReferenceProductHeaderId)
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                     l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)
        # Set other values
        output_handler.set_string_value("//Annex_Code", "RTA")
        output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
        output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                        l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                        l_L2L2CoarseRatio)
        xml_tools.set_string_list_value_sorted_by_attribute(
            output_handler.root,
            self.listofbandtheoreticalwavelengthforreflectancescomposite,
            "//List_of_Band_Theoretical_Wavelength",
            "Band_Theoretical_Wavelength", "count", "sn", 1, l_attr)
        output_handler.set_string_value(
            "//Bands",
            len(self.listofbandtheoreticalwavelengthforreflectancescomposite))
        # Save file
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
        # ---------------------------------------------------------------------------------------------------
        # Write RTC
        LOGGER.debug("Write the PRIVATE RTA header file ...")
        output_filename = p_L2PrivateImageFilenamesProvider.get_rtc_header_filename(
        )
        current_header_filename = os.path.join(
            p_root_template_directory,
            self.plugin.TEMPLATE_PDTANX_PRIVATE_RCR_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaExceptionPluginBase(
                "Internal error: the template file '" +
                current_header_filename + "' doesn't exist !!")
        # ---------------------------------------------------------------------------------------------------
        # Load the file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version,
                              output_filename, self.creator, lCreator_Version,
                              self.notes, self.system, self.outputfileclass,
                              pCurrentDate, lReferenceProductHeaderId)
        # ---------------------------------------------------------------------------------------------
        # Update bascis ANX parameters
        output_handler.update_pdtanx(p_Mission, l_CoarseProductImageSizeX,
                                     l_CoarseProductImageSizeY,
                                     lReferenceProductInstance,
                                     self.productisvalid)

        output_handler.set_string_value("//Annex_Code", "RTC")
        output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
        output_handler.set_string_value("//Subsampling_Factor/By_Line",
                                        l_L2L2CoarseRatio)
        output_handler.set_string_value("//Subsampling_Factor/By_Column",
                                        l_L2L2CoarseRatio)
        xml_tools.set_string_list_value_sorted_by_attribute(
            output_handler.root,
            self.listofbandtheoreticalwavelengthforreflectancescomposite,
            "//List_of_Band_Theoretical_Wavelength",
            "Band_Theoretical_Wavelength", "count", "sn", 1, l_attr)
        output_handler.set_string_value(
            "//Bands",
            len(self.listofbandtheoreticalwavelengthforreflectancescomposite))
        # Save file
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid and p_EnableCheckXMLFilesWithSchema:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
    def initialize(self,
                   reference_base_filename,
                   validate=False,
                   schema_path=None):
        LOGGER.debug("Start Venus L1 VenusL1ImageFilenamesProvider ...")
        LOGGER.debug("Analyse of the reference base filename: '" +
                     reference_base_filename + "'")

        # Set GLOBAL HDR image filename
        l_dblfilename = os.path.splitext(reference_base_filename)[0] + ".DBL"
        l_FileNameDBL_DIR = os.path.splitext(
            reference_base_filename)[0] + ".DBL.DIR"

        if not (os.path.exists(l_dblfilename)
                or os.path.exists(l_FileNameDBL_DIR)):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The GLOBAL Product file .DBL "
                + l_dblfilename + "' doesn't exist !! The " +
                reference_base_filename + " product is NOT valid !")

        # Expand the path
        l_refFileName = os.path.splitext(reference_base_filename)[0] + ".HDR"
        LOGGER.debug("m_hdrfilename: '" + l_refFileName + "'")

        if not os.path.exists(l_refFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The GLOBAL Header file .HDR "
                + l_refFileName + " The" + reference_base_filename +
                " product is NOT valid !")
        self.m_hdrfilename = l_refFileName

        if schema_path:
            LOGGER.debug("Root shemas install directory '" + schema_path + "'")
            lSchemaLocationDirectory = schema_path + self.plugin.MAJA_INSTALL_SCHEMAS_DIR

        # Check XML file
        if validate:
            xml_tools.check_xml(self.m_hdrfilename, lSchemaLocationDirectory)

        # Load HDR file
        l_CanLoad = xml_tools.can_load_file(self.m_hdrfilename)
        if not l_CanLoad:
            return False

        # Filename naming convention:
        # VE_TEST_VSC_L1VALD_CAMARGUE_20120101.HDR
        # VE_VM01_VSC_L1VALD__PE_R_U__20120101.HDR
        # XML information
        #        <File_Class>TEST</File_Class>
        #        <File_Type>VSC_L2VALD</File_Type>
        #        <Nick_Name>CAMARGUE</Nick_Name>
        #		  <Acquisition_Date>20120103</Acquisition_Date>
        # Split FileType to extract VSC and L1VALD strings ( from "VSC_L2VALD")

        m_FileClass = EarthExplorerUtilities.get_fileclass_from_filename(
            l_refFileName)


        prefix1 = EarthExplorerUtilities.get_satellite_class_from_filename(l_refFileName) + "_" + \
                  m_FileClass + "_" + \
                  EarthExplorerUtilities.get_file_type_short_from_filename(l_refFileName) + "_"

        prefix2 = "_" + EarthExplorerUtilities.get_level_class_from_filename(l_refFileName) + "_" + \
                  EarthExplorerUtilities.get_nickname_from_global_filename(l_refFileName) + "_" + \
                  EarthExplorerUtilities.get_acquisition_from_global_filename(l_refFileName)

        # *******************************************************************************************************
        # Set TOA image filename
        # *******************************************************************************************************
        # Build the relative filename
        l_FileName = prefix1 + "PDTIMG" + prefix2 + ".DBL.TIF"
        self.m_TOAImageFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)

        LOGGER.debug(self.m_TOAImageFileName)

        if not os.path.exists(self.m_TOAImageFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 TOA filename " +
                str(self.m_TOAImageFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")
        # *******************************************************************************************************
        # Set TOA header filename
        # *******************************************************************************************************
        l_FileName = prefix1 + "PDTIMG" + prefix2 + ".HDR"
        self.m_TOAHeaderFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)
        if not os.path.exists(self.m_TOAHeaderFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 TOA filename " +
                str(self.m_TOAHeaderFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")
        # Check XML file
        if validate:
            xml_tools.check_xml(self.m_TOAHeaderFileName,
                                lSchemaLocationDirectory)

        # *******************************************************************************************************
        # Set CLA image filename
        # *******************************************************************************************************
        l_FileName = prefix1 + "PDTANX" + prefix2 + "_CLA.DBL.TIF"
        self.m_CLAImageFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)
        if not os.path.exists(self.m_CLAImageFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 CLA filename " +
                str(self.m_CLAImageFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")
        # *******************************************************************************************************
        # Set CLA header filename
        # *******************************************************************************************************
        l_FileName = prefix1 + "PDTANX" + prefix2 + "_CLA.HDR"
        self.m_CLAHeaderFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)
        if not os.path.exists(self.m_CLAHeaderFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 CLA filename " +
                str(self.m_CLAHeaderFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")
        # Check XML file
        if validate:
            xml_tools.check_xml(self.m_CLAHeaderFileName,
                                lSchemaLocationDirectory)

        # *******************************************************************************************************
        # Set SOL image filename
        # *******************************************************************************************************
        l_FileName = prefix1 + "PDTANX" + prefix2 + "_SOL.DBL.HDF"
        self.m_SOLImageFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)
        if not os.path.exists(self.m_SOLImageFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 SOL filename " +
                str(self.m_SOLImageFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")

        # *******************************************************************************************************
        # Set SOL header filename
        # *******************************************************************************************************
        l_FileName = prefix1 + "PDTANX" + prefix2 + "_SOL.HDR"
        self.m_SOLHeaderFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)
        if not os.path.exists(self.m_SOLHeaderFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 SOL filename " +
                str(self.m_SOLHeaderFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")
        # Check XML file
        if validate:
            xml_tools.check_xml(self.m_SOLHeaderFileName,
                                lSchemaLocationDirectory)

        # *******************************************************************************************************
        # Set VIE image filename
        # *******************************************************************************************************
        l_FileName = prefix1 + "PDTANX" + prefix2 + "_VIE.DBL.HDF"
        self.m_VIEImageFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)
        if not os.path.exists(self.m_VIEImageFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 VIE filename " +
                str(self.m_VIEImageFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")
        # *******************************************************************************************************
        # Set VIE header filename
        # *******************************************************************************************************
        l_FileName = prefix1 + "PDTANX" + prefix2 + "_VIE.HDR"
        self.m_VIEHeaderFileName = os.path.join(l_FileNameDBL_DIR, l_FileName)
        if not os.path.exists(self.m_VIEHeaderFileName):
            raise MajaExceptionPluginBase(
                "VenusL1ImageFilenames Provider: The L1 VIE filename " +
                str(self.m_VIEHeaderFileName) + " doesn't exist. The " +
                str(reference_base_filename) + "product is NOT valid !")
        # Check XML file
        if validate:
            xml_tools.check_xml(self.m_VIEHeaderFileName,
                                lSchemaLocationDirectory)

        return True
    def write_public_xml_handler(self, p_L2ImageFilenamesProvider, p_dem, p_Validity_Start, p_Validity_Stop, p_Mission,
                              p_root_template_directory, p_SchemaLocationDirectory, pCurrentDate):

        l_NumberOfResolutions = len(p_L2ImageFilenamesProvider.get_sre_headers())
        LOGGER.debug("L2ImageFileReader::Initialize Number of resolutions: " + str(l_NumberOfResolutions) + ".")

        # Write Public Headers

        output_filename = ""
        # ---------------------------------------
        # Get global information about the output L2 product
        # ---------------------------------------
        lCreator_Version = self.plugin.Creator_Version
        lFile_Version = self.plugin.L2PRODUCT_FILE_VERSION
        # Get Validity
        lReferenceProductHeaderId = p_L2ImageFilenamesProvider.get_reference_product_header_id()
        lReferenceProductInstance = p_L2ImageFilenamesProvider.get_reference_product_instance()
        LOGGER.debug("p_L2ImageFilenamesProvider->GetReferenceProductHeaderId() <" +
                     p_L2ImageFilenamesProvider.get_reference_product_header_id() + ">")
        LOGGER.debug("p_L2ImageFilenamesProvider->GetReferenceProductInstance() <" +
                     p_L2ImageFilenamesProvider.get_reference_product_instance() + ">")
        LOGGER.debug("Writing xml file <" + output_filename + ">...")
        # ---------------------------------------------------------------------------------------------------
        l_CoarseProductImageSizeX = p_dem.CoarseArea.size[0]
        l_CoarseProductImageSizeY = p_dem.CoarseArea.size[1]

        l_CLDNbBits = self.plugin.NumbersOfBitsInCLDDataIOBand
        l_BandsDefinitions = self.plugin.BandsDefinitions

        # *************************************************************************************************************
        # Write headers for all resolution
        # *************************************************************************************************************
        for resol in range(l_NumberOfResolutions):
            # Resolution information
            # ---------------------------------------
            l_ProductImageSizeX = p_dem.L2Areas[resol].size[0]
            l_ProductImageSizeY = p_dem.L2Areas[resol].size[1]
            l_ResollistOfBandCode = l_BandsDefinitions.get_list_of_l2_band_code(l_BandsDefinitions.ListOfL2Resolution[resol])

            # Write Public Headers
            if self.adjacencyeffectsandslopecorrection:
                # ---------------------------------------------------------------------------------------------------
                # Write FRE
                LOGGER.debug("Write the FRE header file ...")
                output_filename = p_L2ImageFilenamesProvider.get_fre_headers()[resol]

                current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTIMG_HDR)
                output_handler = EarthExplorerXMLFileHandler(current_header_filename)
                if not os.path.exists(current_header_filename):
                    raise MajaDataException(
                        "Internal error: the template file '" +
                        current_header_filename +
                        "' doesn't exist !!")
                LOGGER.debug("Update file ...")
                # Update bascis parameters
                output_handler.update(
                    p_Validity_Start,
                    p_Validity_Stop,
                    lFile_Version,
                    output_filename,
                    self.creator,
                    lCreator_Version,
                    self.notes,
                    self.system,
                    self.outputfileclass,
                    pCurrentDate,
                    lReferenceProductHeaderId)

                # ---------------------------------------------------------------------------------------------
                # Update bascis ANX parameters
                output_handler.update_pdtanx(
                    p_Mission,
                    l_ProductImageSizeX,
                    l_ProductImageSizeY,
                    lReferenceProductInstance,
                    self.productisvalid)
                output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
                output_handler.set_list_of_bands(l_ResollistOfBandCode)  # , "//List_of_Bands", "Band")
                output_handler.set_string_value("//Bands", str(len(l_ResollistOfBandCode)))
                # Save File
                LOGGER.debug("SaveFile file ...")
                output_handler.save_to_file(output_filename)
                if self.checkxmlfileswithschema and self.productisvalid:
                    xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)

            # ---------------------------------------------------------------------------------------------------
            # Write SRE
            LOGGER.debug("Write the SRE header file ...")
            output_filename = p_L2ImageFilenamesProvider.get_sre_headers()[resol]
            LOGGER.debug("p_L2ImageFilenamesProvider->GetReferenceProductHeaderId() <" +
                         p_L2ImageFilenamesProvider.get_reference_product_header_id() + ">")
            LOGGER.debug("p_L2ImageFilenamesProvider->GetReferenceProductInstance() <" +
                         p_L2ImageFilenamesProvider.get_reference_product_instance() + ">")
            LOGGER.debug("Writing xml file <" + output_filename + ">...")
            current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTIMG_HDR)
            if not os.path.exists(current_header_filename):
                raise MajaDataException(
                    "Internal error: the template file '" + current_header_filename + "' doesn't exist !!")
            output_handler = EarthExplorerXMLFileHandler(current_header_filename)
            # ---------------------------------------------------------------------------------------------
            # Update bascis parameters
            output_handler.update(
                p_Validity_Start,
                p_Validity_Stop,
                lFile_Version,
                output_filename,
                self.creator,
                lCreator_Version,
                self.notes,
                self.system,
                self.outputfileclass,
                pCurrentDate,
                lReferenceProductHeaderId)
            # ---------------------------------------------------------------------------------------------
            # Update bascis ANX parameters
            output_handler.update_pdtanx(p_Mission, l_ProductImageSizeX, l_ProductImageSizeY, lReferenceProductInstance,
                                         self.productisvalid)
            output_handler.set_string_value("//Nodata_Value", self.nodatavalue)
            output_handler.set_list_of_bands(l_ResollistOfBandCode)  # , "//List_of_Bands", "Band")
            output_handler.set_string_value("//Bands", str(len(l_ResollistOfBandCode)))
            LOGGER.debug("SaveFile file ...")
            # Save File
            output_handler.save_to_file(output_filename)
            if self.checkxmlfileswithschema and self.productisvalid:
                xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
            # ---------------------------------------------------------------------------------------------------
            # Write ATB
            LOGGER.debug("Write the ATB header file ...")
            output_filename = p_L2ImageFilenamesProvider.get_atb_header_filenames()[resol]
            current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTANX_ATB_HDR)
            if not os.path.exists(current_header_filename):
                raise MajaDataException(
                    "Internal error: the template file '" + current_header_filename + "' doesn't exist !!")
            output_handler = EarthExplorerXMLFileHandler(current_header_filename)
            # ---------------------------------------------------------------------------------------------
            # Update bascis parameters
            output_handler.update(
                p_Validity_Start,
                p_Validity_Stop,
                lFile_Version,
                output_filename,
                self.creator,
                lCreator_Version,
                self.notes,
                self.system,
                self.outputfileclass,
                pCurrentDate,
                lReferenceProductHeaderId)

            # ---------------------------------------------------------------------------------------------
            # Update bascis ANX parameters
            output_handler.update_pdtanx(p_Mission, l_ProductImageSizeX, l_ProductImageSizeY, lReferenceProductInstance,
                                         self.productisvalid)
            output_handler.set_string_value("//VAP_Nodata_Value", self.vapnodatavalue)
            output_handler.set_string_value("//VAP_Quantification_Value", self.vapquantificationvalue)
            output_handler.set_string_value("//AOT_Nodata_Value", self.aotnodatavalue)
            output_handler.set_string_value("//AOT_Quantification_Value", self.aotquantificationvalue)
            # Save File
            output_handler.save_to_file(output_filename)
            if self.checkxmlfileswithschema and self.productisvalid:
                xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
            # ---------------------------------------------------------------------------------------------------
            # Write CLD
            LOGGER.debug("Write the CLD header file ...")
            output_filename = p_L2ImageFilenamesProvider.get_cld_header_filenames()[resol]
            current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTANX_CLD_HDR)
            if not os.path.exists(current_header_filename):
                raise MajaDataException(
                    "Internal error: the template file '" + current_header_filename + "' doesn't exist !!")
            output_handler = EarthExplorerXMLFileHandler(current_header_filename)
            # ---------------------------------------------------------------------------------------------
            # Update bascis parameters
            output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version, output_filename, self.creator,
                                  lCreator_Version,
                                  self.notes, self.system, self.outputfileclass, pCurrentDate,
                                  lReferenceProductHeaderId)
            output_handler.set_string_value("//Number_of_Significant_Bits", l_CLDNbBits)
            if l_CLDNbBits <= 8:
                output_handler.set_string_value("//Data_Type", "UNSIGNED_BYTE")
            elif l_CLDNbBits <= 16:
                output_handler.set_string_value("//Data_Type", "UNSIGNED_SHORT")
            else:
                raise MajaDataException("Internal error:  CLD band must be written with [1..16] bits !")
            # ---------------------------------------------------------------------------------------------
            # Update bascis ANX parameters
            output_handler.update_pdtanx(p_Mission, l_ProductImageSizeX, l_ProductImageSizeY, lReferenceProductInstance,
                                         self.productisvalid)
            # Save File
            output_handler.save_to_file(output_filename)
            if self.checkxmlfileswithschema and self.productisvalid:
                xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
            # ---------------------------------------------------------------------------------------------------
            # Write MSK
            LOGGER.debug("Write the MSK header file ...")
            output_filename = p_L2ImageFilenamesProvider.get_msk_header_filenames()[resol]
            current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTANX_MSK_HDR)
            if not os.path.exists(current_header_filename):
                raise MajaDataException(
                    "Internal error: the template file '" + current_header_filename + "' doesn't exist !!")
            output_handler = EarthExplorerXMLFileHandler(current_header_filename)
            # ---------------------------------------------------------------------------------------------
            # Update bascis parameters
            output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version, output_filename, self.creator,
                                  lCreator_Version,
                                  self.notes, self.system, self.outputfileclass, pCurrentDate,
                                  lReferenceProductHeaderId)
            # ---------------------------------------------------------------------------------------------
            # Update bascis ANX parameters
            output_handler.update_pdtanx(p_Mission, l_ProductImageSizeX, l_ProductImageSizeY, lReferenceProductInstance,
                                         self.productisvalid)
            # Save File
            output_handler.save_to_file(output_filename)
            if self.checkxmlfileswithschema and self.productisvalid:
                xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
            # ---------------------------------------------------------------------------------------------------
            # Write QLT
            LOGGER.debug("Write the QLT header file ...")
            output_filename = p_L2ImageFilenamesProvider.get_qlt_header_filenames()[resol]
            current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTANX_QLT_HDR)
            if not os.path.exists(current_header_filename):
                raise MajaDataException(
                    "Internal error: the template file '" + current_header_filename + "' doesn't exist !!")
            output_handler = EarthExplorerXMLFileHandler(current_header_filename)
            # ---------------------------------------------------------------------------------------------
            # Update bascis parameters
            output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version, output_filename, self.creator,
                                  lCreator_Version,
                                  self.notes, self.system, self.outputfileclass, pCurrentDate,
                                  lReferenceProductHeaderId)
            # ---------------------------------------------------------------------------------------------
            # Update bascis ANX parameters
            output_handler.update_pdtanx(p_Mission, l_ProductImageSizeX, l_ProductImageSizeY, lReferenceProductInstance,
                                         self.productisvalid)
            # Save File
            output_handler.save_to_file(output_filename)
            if self.checkxmlfileswithschema and self.productisvalid:
                xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
        # ---------------------------------------------------------------------------------------------------
        # Write QLK
        LOGGER.debug("Write the QLK header file ...")
        output_filename = p_L2ImageFilenamesProvider.get_qlk_header_filename()
        current_header_filename = os.path.join(p_root_template_directory, self.plugin.TEMPLATE_PDTQLK_HDR)
        if not os.path.exists(current_header_filename):
            raise MajaDataException(
                "Internal error: the template file '" + current_header_filename + "' doesn't exist !!")
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------------------------------------------------------------
        # Update bascis parameters
        output_handler.update(p_Validity_Start, p_Validity_Stop, lFile_Version, output_filename, self.creator,
                              lCreator_Version,
                              self.notes, self.system, self.outputfileclass, pCurrentDate,
                              lReferenceProductHeaderId)
        output_handler.set_string_value("//Mission", p_Mission)
        output_handler.set_string_value("//Lines", l_CoarseProductImageSizeY)
        output_handler.set_string_value("//Columns", l_CoarseProductImageSizeX)
        # Instance_Id node
        output_handler.set_string_value("//Reference_Product_Instance", lReferenceProductInstance)
        if self.productisvalid:
            output_handler.set_string_value("//Reference_Product_Semantic", "L2VALD")
        else:
            output_handler.set_string_value("//Reference_Product_Semantic", "L2NOTV")
        # Set the band informations
        listOfBands = list()
        listOfBands.append(self.quicklookredbandcode)
        listOfBands.append(self.quicklookgreenbandcode)
        listOfBands.append(self.quicklookbluebandcode)
        output_handler.set_string_value("//Bands", "3")
        RedBandId = 0
        GreenBandId = 0
        BlueBandId = 0
        ResolutionIndex = 0
        l_ResolutionForQLK = ""
        l_BandsDefinitions.get_l2_information_for_quicklook_band_code(
            self.quicklookredbandcode,
            self.quicklookgreenbandcode,
            self.quicklookbluebandcode
        )
        l_DL2L2CoarseRatio = float(p_dem.L2Areas[ResolutionIndex].size[0]) / float(p_dem.CoarseArea.size[0])
        l_L2L2CoarseRatio = int(l_DL2L2CoarseRatio + 0.5)

        output_handler.set_string_value("//Subsampling_Factor", l_L2L2CoarseRatio)
        output_handler.set_list_of_bands(listOfBands)  # , "//List_of_Bands", "Band")
        # Save File
        output_handler.save_to_file(output_filename)
        if self.checkxmlfileswithschema and self.productisvalid:
            xml_tools.check_xml(output_filename, p_SchemaLocationDirectory)
    def write_global_xmlhandler(self, root_sc_xml_templates,
                                l1_input_xmlhandler, l1_input_tile_xmlhandler,
                                output_filename, p_FileType,
                                schemaLocationDirectory):
        input_dir = self.l2imagefilenamesprovider.m_PublicDirectory
        # Get global information about the output L2 product
        # ---------------------------------------
        lCurrentDate = datetime.datetime.now().strftime(
            EarthExplorerXMLFileHandler.XML_FORMAT_DATE)
        lCreator_Version = "3.2.2"
        lFile_Version = self.plugin.L2PRODUCT_FILE_VERSION
        # ---------------------------------------------------------------------------------------------------
        LOGGER.debug("Write the GLOBAL header file ...")
        current_header_filename = root_sc_xml_templates
        if not os.path.exists(current_header_filename):
            raise MajaDataException("Internal error: the template file '" +
                                    current_header_filename +
                                    "' doesn't exist !!")
        # ---------------------------------------------------------------------------------------------
        # Load the template file used to writes the new header file
        output_handler = EarthExplorerXMLFileHandler(current_header_filename)
        # ---------------------------------------
        # Set the main header information
        # ---------------------------------------
        EE_File_Name = os.path.basename(output_filename)
        LOGGER.debug("output_filename: " + output_filename)
        output_handler.set_string_value("//File_Version", lFile_Version)
        output_handler.set_string_value("//File_Name",
                                        os.path.splitext(EE_File_Name)[0])
        output_handler.set_string_value("//Mission",
                                        l1_input_xmlhandler.get_mission())
        output_handler.set_string_value(
            "//Validity_Start",
            l1_input_tile_xmlhandler.get_validity_start_date())
        output_handler.set_string_value(
            "//Validity_Stop",
            l1_input_tile_xmlhandler.get_validity_stop_date())
        output_handler.set_string_value("//Creator", self.creator)
        output_handler.set_string_value("//Creator_Version", lCreator_Version)
        output_handler.set_string_value("//Notes", self.notes)
        output_handler.set_string_value("//System", self.system)
        output_handler.set_string_value("//File_Class", self.outputfileclass)
        output_handler.set_string_value("//File_Type", p_FileType)
        output_handler.set_string_value("//Creation_Date", lCurrentDate)
        # Nick_Name
        # Format site under 8 characters
        output_handler.set_string_value(
            "//Nick_Name",
            maja_utils.get_formated_site(
                self.l1imageinformationsproviderbase.Site))

        # Acquisition_Date
        output_handler.set_string_value(
            "//Acquisition_Date",
            l1_input_tile_xmlhandler.get_date_formated_yyyymmdd())

        if self.initmode:
            output_handler.set_string_value(
                "//Processing_Flags_And_Modes/Processing_Mode", "INIT_MODE")
        elif self.backwardmode:
            output_handler.set_string_value(
                "//Processing_Flags_And_Modes/Processing_Mode",
                "BACKWARD_MODE")
        else:
            output_handler.set_string_value(
                "//Processing_Flags_And_Modes/Processing_Mode",
                "STANDARD_MODE")
        output_handler.set_string_value(
            "//Adjacency_Effects_And_Slope_Correction",
            self.adjacencyeffectsandslopecorrection)
        output_handler.set_string_value(
            "//Processing_Flags_And_Modes/Cirrus_Correction",
            self.cirruscorrection)

        # Acquisition_Date_Time
        output_handler.set_string_value(
            "//Acquisition_Date_Time",
            l1_input_tile_xmlhandler.get_date_formated_utc())
        output_handler.set_string_value(
            "//Acquisition_Orbit_Number",
            l1_input_xmlhandler.get_string_value_of("OrbitNumber"))

        output_handler.set_string_value("//Web_Site_URL",
                                        self.plugin.WebSiteURL)

        output_handler.set_string_value("//Processing_Information/Date_Time",
                                        lCurrentDate)

        LOGGER.debug("Before WriteListofGIPPFiles")

        # ---------------------------------------
        # List_of_GIPP_Files
        # ---------------------------------------
        listOfGipps = EarthExplorerUtilities.convert_gipp_filenames_to_file_types(
            self.listofgippsfilenames)
        output_handler.write_list_of_gipp_files(listOfGipps)
        # ---------------------------------------
        # List_of_Quality_Indexes
        # ---------------------------------------
        listOfQualityInd = []
        qI = EarthExplorerXMLFileHandler.QualityIndex()
        qI.Code = EarthExplorerXMLFileHandler.CONST_RAIN_DETECTED_NV
        qI.Value = str(self.rainflag)
        listOfQualityInd.append(qI)
        qI = EarthExplorerXMLFileHandler.QualityIndex()
        qI.Code = EarthExplorerXMLFileHandler.CONST_HOTSPOT_DETECTED_NV
        qI.Value = str(self.hotspotflag)
        listOfQualityInd.append(qI)
        qI = EarthExplorerXMLFileHandler.QualityIndex()
        qI.Code = EarthExplorerXMLFileHandler.CONST_SUNGLINT_DETECTED_NV
        qI.Value = str(self.sunglintflag)
        listOfQualityInd.append(qI)
        # Since 4-1-0, writes the Cirrus flag if GetCirrusFlag() OR
        # GetCirrusMasking() activated. See #126349 (  FD
        # https:#thor.si.c-s.fr/gf/project/maccs/tracker/?action=TrackerItemEdit&tracker_item_id=126349
        # )
        if self.plugin.CirrusFlag or self.plugin.CirrusMasking:
            qI = EarthExplorerXMLFileHandler.QualityIndex()
            qI.Code = EarthExplorerXMLFileHandler.CONST_CIRRUS_DETECTED_NV
            qI.Value = str(self.cirrusflag)
            listOfQualityInd.append(qI)

        output_handler.write_list_of_quality_indexes(listOfQualityInd)

        # ---------------------------------------
        # Set information in the Geometry block for each resolution
        # ---------------------------------------
        l_UL_R1 = l1_input_tile_xmlhandler.get_geoposition_upperleftcorner(10)
        l_UL_R2 = l1_input_tile_xmlhandler.get_geoposition_upperleftcorner(20)

        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='10']/Geoposition/ULX",
            str(l_UL_R1.x))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='10']/Geoposition/ULY",
            str(l_UL_R1.y))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='20']/Geoposition/ULX",
            str(l_UL_R2.x))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='20']/Geoposition/ULY",
            str(l_UL_R2.y))

        l_DIM_R1 = l1_input_tile_xmlhandler.get_geoposition_dims(10)
        l_DIM_R2 = l1_input_tile_xmlhandler.get_geoposition_dims(20)

        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='10']/Geoposition/XDIM",
            str(l_DIM_R1.x))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='10']/Geoposition/YDIM",
            str(l_DIM_R1.y))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='20']/Geoposition/XDIM",
            str(l_DIM_R2.x))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='20']/Geoposition/YDIM",
            str(l_DIM_R2.y))

        l_ProductImageSizeX = self.dem.L2Areas[0].size[0]
        l_ProductImageSizeY = self.dem.L2Areas[0].size[1]
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='10']/Size/Lines",
            str(l_ProductImageSizeY))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='10']/Size/Columns",
            str(l_ProductImageSizeX))

        l_ProductImageSizeX = self.dem.L2Areas[1].size[0]
        l_ProductImageSizeY = self.dem.L2Areas[1].size[1]
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='20']/Size/Lines",
            str(l_ProductImageSizeY))
        output_handler.set_string_value(
            "//Image_Information/List_of_Resolutions/Resolution[@r='20']/Size/Columns",
            str(l_ProductImageSizeX))

        # ---------------------------------------
        # Set solar and viewing angles
        # ---------------------------------------
        # LAIG-FA-MAC-135662-CS : values set in the l1_input_tile_handler and not in the l1_input_handler
        # Solar_Angles
        xml_tools.replace_node(l1_input_tile_xmlhandler.root,
                               "//Tile_Angles/Mean_Sun_Angle",
                               output_handler.root, "//Mean_Sun_Angle")
        xml_tools.replace_node(l1_input_tile_xmlhandler.root,
                               "//Mean_Viewing_Incidence_Angle_List",
                               output_handler.root,
                               "//Mean_Viewing_Incidence_Angle_List")

        xml_tools.copies_to_child(l1_input_tile_xmlhandler.root,
                                  "//Tile_Angles/Sun_Angles_Grid/*",
                                  output_handler.root, "//Solar_Angles")
        xml_tools.copies_to_child(l1_input_tile_xmlhandler.root,
                                  "//Viewing_Incidence_Angles_Grids",
                                  output_handler.root,
                                  "//List_of_Viewing_Angles")

        output_handler.set_string_value(
            "//Reflectance_Quantification_Value",
            f"{self.reflectancequantificationvalue:.9f}")

        # ---------------------------------------
        # Set Cloud_Percentage
        # ---------------------------------------
        output_handler.set_string_value("//Cloud_Percentage", self.cloudrate)

        # ---------------------------------------
        # Set Snow_Percentage
        # ---------------------------------------
        output_handler.set_string_value("//Snow_Percentage", self.snowrate)

        # ---------------------------------------
        # Set DEM statistics
        # ---------------------------------------
        output_handler.set_string_value("//Used_DEM/DEM_Reference",
                                        self.dem.ALT_LogicalName)
        output_handler.set_string_value("//Used_DEM/Statistics/Min",
                                        f"{self.dem.ALT_Min:.9f}")
        output_handler.set_string_value("//Used_DEM/Statistics/Max",
                                        f"{self.dem.ALT_Max:.9f}")
        output_handler.set_string_value("//Used_DEM/Statistics/Average",
                                        f"{self.dem.ALT_Mean:.9f}")
        output_handler.set_string_value(
            "//Used_DEM/Statistics/Standard_Deviation",
            f"{self.dem.ALT_Stdv:.9f}")

        output_handler.set_string_value("//Nodata_Value", self.nodatavalue)

        # , "//List_of_Used_Product_Ids", "Used_Product_Id");
        output_handler.set_list_of_used_products_ids(
            self.listofusedproductsids)

        # ---------------------------------------
        # Resolution information
        # ---------------------------------------
        l_NbResolution = len(
            self.l2imagefilenamesprovider.get_sre_regular_filenames())
        for resol in range(l_NbResolution):
            # ---------------------------------------
            # Product_Organization block per resolution
            # ---------------------------------------
            # Image_File
            regular_sre = self.l2imagefilenamesprovider.get_sre_regular_filenames(
            )[resol]
            output_handler.set_string_value(
                "//Product_Organization/Image_File/Nature", regular_sre.Nature)
            output_handler.set_string_value(
                "//Product_Organization/Image_File/Logical_Name",
                regular_sre.LogicalName)
            output_handler.set_string_value(
                "//Product_Organization/Image_File/File_Location",
                regular_sre.FileLocation)
            if self.adjacencyeffectsandslopecorrection:
                regular_fre = self.l2imagefilenamesprovider.get_fre_regular_filenames(
                )[resol]
                xml_tools.copy_to_sibling_inplace(
                    output_handler.root, "//Product_Organization/Image_File",
                    "//Product_Organization/Image_File")
                output_handler.set_string_value(
                    "//Product_Organization/Image_File/Nature",
                    regular_fre.Nature)
                output_handler.set_string_value(
                    "//Product_Organization/Image_File/Logical_Name",
                    regular_fre.LogicalName)
                output_handler.set_string_value(
                    "//Product_Organization/Image_File/File_Location",
                    regular_fre.FileLocation)

        # Quicklook_File
        regular_qlk = self.l2imagefilenamesprovider.get_qlk_regular_file()[0]
        output_handler.set_string_value(
            "//Product_Organization/Quicklook_File/Nature", regular_qlk.Nature)
        output_handler.set_string_value(
            "//Product_Organization/Quicklook_File/Logical_Name",
            regular_qlk.LogicalName)
        output_handler.set_string_value(
            "//Product_Organization/Quicklook_File/File_Location",
            regular_qlk.FileLocation)
        # Annex
        output_handler.write_list_of_annex_files(
            self.l2imagefilenamesprovider.get_list_of_annex_file())
        # Private_Data_File
        regular_hdr = self.l2imagefilenamesprovider.get_private_filenames(
        ).get_hdr_regular_file()
        output_handler.set_string_value(
            "//Product_Organization/Private_Data_File/Nature",
            regular_hdr.Nature)
        output_handler.set_string_value(
            "//Product_Organization/Private_Data_File/Logical_Name",
            regular_hdr.LogicalName)
        output_handler.set_string_value(
            "//Product_Organization/Private_Data_File/File_Location",
            regular_hdr.FileLocation)

        # Reference_SystemCode
        output_handler.set_string_value(
            "//Coordinate_Reference_System/Code",
            l1_input_tile_xmlhandler.get_string_value_of(
                "ReferenceSystemCode"))
        output_handler.set_string_value(
            "//Coordinate_Reference_System/Short_Description",
            l1_input_tile_xmlhandler.get_string_value_of(
                "ReferenceSystemShortDescription"))
        # Save to file
        output_handler.save_to_file(output_filename)
        # Check the GLOBAL header even if  not valid (NOTV)
        if self.checkxmlfileswithschema:
            xml_tools.check_xml(output_filename, schemaLocationDirectory)