예제 #1
0
 def test_object_write(self):
     """
     Test the initialisation of the object
     """
     maja_object = MajaInternalXmlInputAngles(self.values_1, self.values_2,
                                              self.col_step, self.row_step,
                                              self.output_filename)
     maja_object.write()
예제 #2
0
 def write(self, output_directory):
     """
     Write in a internal xml format file
     """
     output_filename = os.path.join(output_directory, "sun_angles.xml")
     LOGGER.debug("Angles output_filename : %s", output_filename)
     writer = MajaInternalXmlInputAngles(
         self.zenith_angle_list_string_values,
         self.azimuth_angle_list_string_values, self.col_step,
         self.row_step, output_filename)
     writer.write()
     return output_filename
예제 #3
0
 def write(self, output_directory):
     """
     Write in a internal xml format file
     """
     output_filename = os.path.join(
         output_directory, "viewing_incidence_angle_b%s_d%s_" %
         (self.band_id, self.detector_id) + ".xml")
     LOGGER.debug("Angles output_filename : %s", output_filename)
     writer = MajaInternalXmlInputAngles(self.zenith_values,
                                         self.azimuth_values, self.col_step,
                                         self.row_step, output_filename)
     writer.write()
     return output_filename
예제 #4
0
    def test_save_view_angles(self):
        self.maja_object = MuscateXMLFileHandler(self.xml_filename)
        view_angle_col_step = int(
            self.maja_object.get_string_value_of("SunAngleColStep"))
        view_angle_row_step = -1 * int(
            self.maja_object.get_string_value_of("SunAngleRowStep"))
        # ATTENTION : * -1 for compatibility negative spacing

        l_ListOfTOABandCode = self.maja_object.get_list_of_band_code(
        )  # ListOfStrings
        for l_band in l_ListOfTOABandCode:
            # Get the list of detectors (index)
            l_ListOfZone = self.maja_object.get_list_of_zones(l_band)
            LOGGER.debug("List of zone : ")
            LOGGER.debug(l_ListOfZone)
            # Get the list of viewing angles in the header file of the tile
            l_zenithVieAngles = self.maja_object.get_viewing_zenithal_angles(
                l_band)
            l_azimuthVieAngles = self.maja_object.get_viewing_azimuthal_angles(
                l_band)

            if len(l_zenithVieAngles) != len(l_azimuthVieAngles):
                raise Exception(
                    "The number of detector for viewing zenithal angles and viewing azimuthal angles is different or null !"
                )

            for detId in range(len(l_ListOfZone)):
                det = l_ListOfZone[detId]
                LOGGER.debug(("ZenithViewingAngles for band " + l_band +
                              " and det " + det + " ,  nb values: " +
                              str(len(l_zenithVieAngles[detId]))))
                LOGGER.debug(l_zenithVieAngles[detId])
                LOGGER.debug(
                    ("AzimuthViewingAngles " + l_band + " and det " + det +
                     " nb values: " + str(len(l_azimuthVieAngles[detId]))))
                LOGGER.debug(l_azimuthVieAngles[detId])
                output_filename = "/tmp/internal_angles_test_{}_{}.xml".format(
                    l_band, det)
                LOGGER.debug(("Angles output_filename : %s", output_filename))
                writer = MajaInternalXmlInputAngles(l_zenithVieAngles[detId],
                                                    l_azimuthVieAngles[detId],
                                                    view_angle_col_step,
                                                    view_angle_row_step,
                                                    output_filename)
                writer.write()
                self.assertTrue(os.path.exists(output_filename),
                                "File does not exist " + output_filename)
예제 #5
0
 def test_object(self):
     """
     Test the initialisation of the object
     """
     maja_object = MajaInternalXmlInputAngles(self.values_1, self.values_2,
                                              self.col_step, self.row_step,
                                              self.output_filename)
     self.assertIsNotNone(maja_object)
예제 #6
0
    def test_save_sun_angles(self):
        self.maja_object = MuscateXMLFileHandler(self.xml_filename)
        sun_angle_col_step = int(
            self.maja_object.get_string_value_of("SunAngleColStep"))
        sun_angle_row_step = -1 * int(
            self.maja_object.get_string_value_of("SunAngleRowStep"))
        # ATTENTION : * -1 for compatibility negative spacing

        l_zenithSolarAngles = self.maja_object.get_sun_zenithal_angles()
        l_azimuthSolarAngles = self.maja_object.get_sun_azimuthal_angles()
        LOGGER.debug(
            ("ZenithSolarAngles nb values: " + str(len(l_zenithSolarAngles))))
        LOGGER.debug(("AzimuthSolarAngles nb values: " +
                      str(len(l_azimuthSolarAngles))))
        LOGGER.debug(("Angles output_filename : %s", self.output_filename))
        writer = MajaInternalXmlInputAngles(l_zenithSolarAngles,
                                            l_azimuthSolarAngles,
                                            sun_angle_col_step,
                                            sun_angle_row_step,
                                            self.output_filename)
        writer.write()
        self.assertTrue(os.path.exists(self.output_filename),
                        "File does not exist")
    def read(self, product_info, app_handler, l2comm, dem, pReadL1Mode):
        """product_info,plugin, l2comm,mode

        :param product_info: L1ImageInformationsBase
        :param pReadL1Mode: ReadL1ModeType
        :return:
        """
        LOGGER.info("Start Sentinel2Muscate L1 ImageFileReader ...")
        product_filename = product_info.HeaderFilename
        LOGGER.info(
            "Start Sentinel2Muscate L1 ImageFileReader with filename : " +
            product_filename)
        working_dir = app_handler.get_directory_manager(
        ).get_temporary_directory("L1Read_", do_always_remove=True)
        self._plugin.initialize(app_handler)
        self._GIPPL2COMMHandler = l2comm
        LOGGER.info("Start Sentinel2Muscate L1 ImageFileReader ...")
        self._ReadL1Mode = pReadL1Mode
        self._dem = dem

        # --------------------------------------
        # Check the extension of th efile. For Muscate, must be .XML (in upper case)
        IsValidSatellite = (product_info.HeaderHandler is not None)
        if not IsValidSatellite:
            raise MajaExceptionPluginSentinel2Muscate(
                "The file <{}> is not a valid Sentinel2 L1 product.".format(
                    product_filename))
        self.m_headerHandler = product_info.HeaderHandler
        # Get satellite name
        self.m_Satellite = product_info.Satellite

        # --------------------------------------
        # Load the header tile file in the xml tile handler to read tile information
        xmlTileFilename = product_info.xmlTileFilename
        l_BandsDefinitions = self._plugin.BandsDefinitions  # BandsDefinitions

        # TOA & masks Reader connection
        l_ListOfTOAImageFileNames = product_info.HeaderHandler.get_list_of_toa_image_filenames(
        )
        l_SatPixFileNames = product_info.HeaderHandler.get_list_of_l1_sat_image_filenames(
        )
        l_DefectivPixFileNames = product_info.HeaderHandler.get_list_of_defective_pixel_image_filenames(
        )
        l_ZoneMaskFileNames = product_info.HeaderHandler.get_map_list_of_detector_footprint_image_filenames(
        )
        l_NoDataMaskFileNames = product_info.HeaderHandler.get_list_of_l1_ndt_image_filenames(
        )
        l_ListOfTOABandCode = product_info.HeaderHandler.get_list_of_band_code(
        )  # ListOfStrings
        l_NbBand = len(l_ListOfTOAImageFileNames)  # int
        l_L1NoData = product_info.L1NoData
        l_ReflectanceQuantificationValue = product_info.ReflectanceQuantification
        l_RealL1NoData = l_L1NoData * l_ReflectanceQuantificationValue  # RealNoDataType

        if (len(l_ListOfTOABandCode) != len(l_ListOfTOAImageFileNames)) or (
                len(l_ListOfTOABandCode) != len(l_SatPixFileNames)) or (
                    len(l_ListOfTOABandCode) != len(l_DefectivPixFileNames)):
            raise MajaExceptionPluginSentinel2Muscate(
                "Sentinel2L1ImageFileReader.CanRead: Internal error: The number of image file, sat file and band code are different !"
            )

        # =======> GENERATE TOA
        # Get calibration coeffs if activated
        l_reflectanceMultiplicationValues = []  # ListOfDoubles
        if xml_tools.as_bool(l2comm.get_value("CalAdjustOption")):
            l_factors = xml_tools.as_float_list(
                l2comm.get_value("CalAdjustFactor"))
            if len(l_factors) != len(l_ListOfTOABandCode):
                raise MajaDataException(
                    "Not the same number of Calibration coeffs than L1 bands ( {}, {} )"
                    .format(len(l_factors), len(l_ListOfTOABandCode)))
            for i in range(len(l_ListOfTOABandCode)):
                l_reflectanceMultiplicationValues.append(
                    l_ReflectanceQuantificationValue * l_factors[i])
        else:
            for i in range(len(l_ListOfTOABandCode)):
                l_reflectanceMultiplicationValues.append(
                    l_ReflectanceQuantificationValue)

        l_ProjectionRef = self._dem.ProjRef
        self.generate_toa(l_ListOfTOAImageFileNames,
                          l_reflectanceMultiplicationValues,
                          working_dir)  # string

        #                                     START READ L1 for ALGORITHMS
        if pReadL1Mode == ReadL1Mode.READ_L1_MODE_FOR_ALGORITHMS:
            # =======> GENERATE TOA SUB IMAGES AT L2 COARSE RESOLUTION
            LOGGER.debug("Start SubSampling ...")
            self.generate_toa_sub_images(working_dir)
            LOGGER.debug("Start SubSampling done.")
            #  the gml mask per L2 resolution per band
            self.generate_mask_rasters(l_SatPixFileNames,
                                       l_DefectivPixFileNames,
                                       l_ZoneMaskFileNames,
                                       l_NoDataMaskFileNames,
                                       l_ListOfTOABandCode, working_dir)

            LOGGER.debug("Filenames Mask Rasters : ")
            LOGGER.debug(l_SatPixFileNames)
            LOGGER.debug(l_DefectivPixFileNames)
            LOGGER.debug(l_ZoneMaskFileNames)
            LOGGER.debug(l_NoDataMaskFileNames)
            LOGGER.debug(l_ListOfTOABandCode)

            # Get the ref altitude
            l_CurrentConfigUserCamera = self._plugin.ConfigUserCamera
            grid_ref_alt = l_CurrentConfigUserCamera.get_Algorithms(
            ).get_GRID_Reference_Altitudes()
            l_VIEHRef = grid_ref_alt.get_VIEHRef()  # double
            l_SOLH1 = grid_ref_alt.get_SOLH1()  # double

            # IPSOL Sub image pipeline connection
            LOGGER.debug("Start IPSOL SubSampling ...")
            sun_angle_col_step = int(
                product_info.HeaderHandler.get_string_value_of(
                    "SunAngleColStep"))
            sun_angle_row_step = int(
                product_info.HeaderHandler.get_string_value_of(
                    "SunAngleRowStep"))
            # ATTENTION : * -1 for compatibility negative spacing
            LOGGER.debug(
                "Angle Resolution Spacing computed in 5000 resolution: " +
                str(sun_angle_col_step) + " , " + str(sun_angle_row_step))

            l_zenithSolarAngles = product_info.HeaderHandler.get_sun_zenithal_angles(
            )
            l_azimuthSolarAngles = product_info.HeaderHandler.get_sun_azimuthal_angles(
            )
            LOGGER.debug("ZenithSolarAngles nb values: " +
                         str(len(l_zenithSolarAngles)))
            LOGGER.debug("AzimuthSolarAngles nb values: " +
                         str(len(l_azimuthSolarAngles)))

            l_solarAngleFile = app_handler.get_directory_manager(
            ).get_temporary_file("sun_angles_") + ".xml"

            LOGGER.debug("Angles output_filename : %s", l_solarAngleFile)
            writer = MajaInternalXmlInputAngles(l_zenithSolarAngles,
                                                l_azimuthSolarAngles,
                                                sun_angle_col_step,
                                                sun_angle_row_step,
                                                l_solarAngleFile)
            writer.write()
            # =======> GENERATE SOLAR ANGLE GRIDS
            self.get_solar_grids(self._dem.ALC, l_solarAngleFile, l_SOLH1,
                                 working_dir)
            LOGGER.debug("Start IPSOL SubSampling done.")

            # IPVIE Sub image pipeline connection
            LOGGER.debug("Start IPVIE SubSampling ...")
            vie_angle_col_step = int(
                product_info.HeaderHandler.get_string_value_of(
                    "SunAngleColStep"))
            vie_angle_row_step = int(
                product_info.HeaderHandler.get_string_value_of(
                    "SunAngleRowStep"))
            LOGGER.debug("For each band ...")
            for l_band in l_ListOfTOABandCode:
                l1BandIdx = l_BandsDefinitions.get_band_id_in_l1(l_band)
                # Get the list of detectors (index)
                l_ListOfZone = product_info.HeaderHandler.get_list_of_zones(
                    l_band)
                # Get the list of viewing angles in the header file of the tile
                l_zenithVieAngles = product_info.HeaderHandler.get_viewing_zenithal_angles(
                    l_band)
                l_azimuthVieAngles = product_info.HeaderHandler.get_viewing_azimuthal_angles(
                    l_band)
                if len(l_zenithVieAngles) != len(l_azimuthVieAngles):
                    raise MajaExceptionPluginSentinel2Muscate(
                        "The number of detector for viewing zenithal angles and viewing azimuthal angles is different or null !"
                    )

                # =======> GENERATE VIEWING ANGLE GRIDS
                self.GetViewingGrids(l_band, l_NbBand, l_VIEHRef,
                                     l_SatPixFileNames[l1BandIdx],
                                     l_ZoneMaskFileNames[l1BandIdx],
                                     l_NoDataMaskFileNames[l1BandIdx],
                                     l_ListOfZone, vie_angle_col_step,
                                     vie_angle_row_step, l_zenithVieAngles,
                                     l_azimuthVieAngles, working_dir)

            # end loop nbBand

            LOGGER.debug("Start IPVIE SubSampling done.")

            # To check mean angle values
            # TODO

            # IPEDGSub and L2EDG pipeline connection
            # =======> GENERATE EDG IMAGES
            self.generate_edg_images(working_dir)
            # L2 TOA image pipeline connection
            # =======> GENERATE L2 TOA IMAGES
            self.generate_l2_toa_images(working_dir)
            # IPSAT Sub and L2SAT image pipeline connection
            # =======> GENERATE SAT IMAGES
            self.generate_sat_images(working_dir)
            # CLA image pipeline connection
            # =======> GENERATE CLA IMAGES
            self.generate_cla_images(l_RealL1NoData, working_dir)

            # Fill the datas
            self.dict_of_vals["IPEDGSubOutput"] = self._edgsubmask
            self.dict_of_vals["SOL1Image"] = self._sol1image
            l_DTMBandCode = xml_tools.as_string_list(
                l2comm.get_value("DTMViewingDirectionBandCode"))[0]
            l_DTMBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse(
                l_DTMBandCode)

            self.dict_of_vals["DTMVIEImage"] = self._vieimagelist[l_DTMBandIdx]

            LOGGER.debug("l_DTMBandIdx : ")
            LOGGER.debug(l_DTMBandIdx)
            self.dict_of_vals["IPTOASubOutput"] = self._sub_toa
            self.dict_of_vals["L2TOAImageList"] = self._l2toaimagelist

            self.dict_of_vals["ViewingZenithMeanMap"] = self._meanZenithMap
            self.dict_of_vals["ViewingAzimuthMeanMap"] = self._meanAzimuthMap

            self.dict_of_vals["CLAImage"] = self._claimage

            self.dict_of_vals["IPSATSubOutput"] = self._subsatimage
            l_CLDBandCode = l2comm.get_value("CLDViewingDirectionBandCode")
            l_CLDBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse(
                l_CLDBandCode)
            LOGGER.debug("l_CLDBandIdx: ")
            LOGGER.debug(l_CLDBandIdx)
            self.dict_of_vals["ShadowVIEImage"] = self._vieimagelist[
                l_CLDBandIdx]
            l_CirrusBandCode = l2comm.get_value("CirrusBandCode")
            l_CirrusBandIdx = self._plugin.BandsDefinitions.get_band_id_in_l2_coarse(
                l_CirrusBandCode)

            LOGGER.debug("l_CirrusBandIdx: ")
            LOGGER.debug(l_CirrusBandIdx)

            self.dict_of_vals["L1TOACirrusImage"] = self._toa_scalar_list[
                l_CirrusBandIdx]

            self.dict_of_vals["AngleZoneMaskList"] = self._l2zoneimagelist
            self.dict_of_vals["L2EDGOutputList"] = self._l2edgmasklist
            self.dict_of_vals["L2SATImageList"] = self._l2satmasklist
            self.dict_of_vals["L2PIXImageList"] = self._l2piximagelist
            self.dict_of_vals["L2DFPImageList"] = self._l2dfpimagelist
    def GetViewingGrids(self, band, nbL1Bands, vieHRef, satFilename,
                        zoneFilenames, nodataFilename, listOfZone,
                        view_angle_col_step, view_angle_row_step,
                        viewing_angles_zenith, viewing_angles_azimuth,
                        working):
        LOGGER.debug("GetViewingGrids - Band: " + band)

        dtm_coarse = self._dem.ALC
        l_BandsDefinitions = self._plugin.BandsDefinitions
        l1BandIdx = l_BandsDefinitions.get_band_id_in_l1(band)

        # ---- Viewing angle Grid --------------------------------------------------------------------
        l_VieAnglesGridList = []
        l_nbDetectors = len(viewing_angles_azimuth)
        # Detector loop
        LOGGER.debug("For each detectors (nb=%s) ...", l_nbDetectors)
        view_resamp_pipeline = OtbPipelineManager()
        for detId in range(len(viewing_angles_azimuth)):
            # Generate an image with the list of viewing angle values set in the header file
            det = listOfZone[detId]
            LOGGER.debug("ZenithViewingAngles for band " + band + " and det " +
                         det + " ,  nb values: " +
                         str(len(viewing_angles_zenith[detId])))
            LOGGER.debug(viewing_angles_zenith[detId])
            LOGGER.debug("AzimuthViewingAngles " + band + " and det " + det +
                         " nb values: " +
                         str(len(viewing_angles_azimuth[detId])))
            LOGGER.debug(viewing_angles_azimuth[detId])
            output_filename = "/tmp/internal_angles_test_{}_{}.xml".format(
                band, det)
            LOGGER.debug("Angles output_filename : %s", output_filename)
            writer = MajaInternalXmlInputAngles(viewing_angles_zenith[detId],
                                                viewing_angles_azimuth[detId],
                                                view_angle_col_step,
                                                view_angle_row_step,
                                                output_filename)
            writer.write()
            if not os.path.exists(output_filename):
                raise MajaExceptionPluginSentinel2Muscate(
                    "File does not exist " + output_filename)

            viewing_grid_filename = os.path.join(
                working, "viewing_grid_{}_{}.tif".format(det, band))

            # angle_list_to_image()
            viewing_angle_app = angle_list_to_image(dtm_coarse,
                                                    output_filename,
                                                    viewing_grid_filename,
                                                    extrapolation=False,
                                                    write_output=False)
            view_resamp_pipeline.add_otb_app(viewing_angle_app)
            # Expand at L2Coarse.
            viewing_grid_resamp_filename = os.path.join(
                working, "viewing_grid_resamp_{}_{}.tif".format(detId, band))
            viewing_grid_resamp_app = resample(
                viewing_angle_app.getoutput().get("out"),
                dtm_coarse,
                viewing_grid_resamp_filename,
                OtbResampleType.LINEAR,
                write_output=False)
            view_resamp_pipeline.add_otb_app(viewing_grid_resamp_app)
            # add images in a list
            l_VieAnglesGridList.append(
                viewing_grid_resamp_app.getoutput().get("out"))
            # end detector loop

        # Generate the angle images using the zone (detector) mask
        LOGGER.debug(
            "Start ConcatenatePerZoneVectorImageFilter for band id [" + band +
            "]...")

        # Concatenate all the detectors
        viewing_concat_filename = os.path.join(
            working, "viewing_concat_{}.tif".format(band))
        param_concat_perzone = {
            "mask": self._zonemasksublist[l1BandIdx],
            "il": l_VieAnglesGridList,
            "zonelist": listOfZone,
            "out": viewing_concat_filename
        }
        concat_perzone_app = OtbAppHandler("ConcatenatePerZone",
                                           param_concat_perzone,
                                           write_output=False)
        # Multiply by reference altitude
        viewing_grid_mult_filename = os.path.join(
            working, "viewing_grid_mult_{}.tif".format(band))
        param_scaled_solar = {
            "im": concat_perzone_app.getoutput().get("out"),
            "coef": float(vieHRef),
            "out": viewing_grid_mult_filename
        }
        view_scale_app = OtbAppHandler("MultiplyByScalar",
                                       param_scaled_solar,
                                       write_output=True)
        self._vieimagelist.append(view_scale_app.getoutput().get("out"))

        l_nbZones = len(listOfZone)
        LOGGER.debug("Start Loop for Zone (nb=" + str(l_nbZones) + ")...")
        for d in range(l_nbZones):
            l_zone = listOfZone[d]
            # -----------------------------------------------------------------------------------
            # Compute average values of zenithal and azimuthal angles grid per zone (detector in level1B)
            # -----------------------------------------------------------------------------------
            # VAP Reader connection (from ATB)
            tmp_azi = os.path.join(working,
                                   "tmp_azi_{}_{}.tif".format(band, l_zone))
            tmp_azi_image = extract_roi(l_VieAnglesGridList[d], [1],
                                        tmp_azi,
                                        write_output=False)
            param_stats = {
                "im": tmp_azi_image.getoutput().get("out"),
                "exclude": 1,
                "mask": self._zonemasksublist[l1BandIdx],
                "maskforeground": int(l_zone)
            }
            l2_stat = OtbAppHandler("Stats", param_stats)

            azi_mean = l2_stat.getoutput().get("mean")
            tmp_zen = os.path.join(working,
                                   "tmp_zen_{}_{}.tif".format(band, l_zone))
            tmp_zen_app = extract_roi(l_VieAnglesGridList[d], [0],
                                      tmp_zen,
                                      write_output=False)
            param_stats = {
                "im": tmp_zen_app.getoutput().get("out"),
                "exclude": 1,
                "mask": self._zonemasksublist[l1BandIdx],
                "maskforeground": int(l_zone)
            }
            l2_stat = OtbAppHandler("Stats", param_stats)
            zen_mean = l2_stat.getoutput().get("mean")
            tmp_mean = (zen_mean, azi_mean)
            l_ViewingAngleMean = grid_to_angle(tmp_mean)
            l_ViewingAngleMeanDeg = (l_ViewingAngleMean[0] * 180.0 / math.pi,
                                     l_ViewingAngleMean[1] * 180.0 / math.pi)
            # Add a vector to mean maps
            if l_zone not in self._meanZenithMap:
                self._meanZenithMap[listOfZone[d]] = []
            if l_zone not in self._meanAzimuthMap:
                self._meanAzimuthMap[listOfZone[d]] = []
            self._meanZenithMap[listOfZone[d]].append(
                str(l_ViewingAngleMeanDeg[0]))
            self._meanAzimuthMap[listOfZone[d]].append(
                str(l_ViewingAngleMeanDeg[1]))
            LOGGER.debug(" For BandId[" + str(band) + "], zone [" +
                         str(listOfZone[d]) + "]  . Mean 'GRID View angles'=" +
                         str(tmp_mean) + " . Mean 'View angles'=" +
                         str(l_ViewingAngleMean[0]) + ":" +
                         str(l_ViewingAngleMean[1]) + " rad. ou  " +
                         str(l_ViewingAngleMeanDeg[0]) + ":" +
                         str(l_ViewingAngleMeanDeg[1]) + " deg.")
        LOGGER.debug("Start Loop for Zone done.")
        view_resamp_pipeline.free_otb_app()