From 7c62d1a24c18a49a0ba08d49858ef8e228cb41d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABlle=20USSEGLIO?= <gaelle.usseglio@cnes.fr> Date: Mon, 3 Dec 2018 16:32:00 +0000 Subject: [PATCH] ENH : New application SARDeramp (part 2) --- app/CMakeLists.txt | 5 + app/otbSARDeramp.cxx | 127 +++++++++ include/otbSARDerampImageFilter.h | 97 ++++++- include/otbSARDerampImageFilter.txx | 393 +++++++++++++++++----------- 4 files changed, 460 insertions(+), 162 deletions(-) create mode 100644 app/otbSARDeramp.cxx diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 25a31f4..101e0fd 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -83,3 +83,8 @@ OTB_CREATE_APPLICATION(NAME SARGridStatistics SOURCES otbSARGridStatistics.cxx LINK_LIBRARIES ${${otb-module}_LIBRARIES} ) + +OTB_CREATE_APPLICATION(NAME SARDeramp + SOURCES otbSARDeramp.cxx + LINK_LIBRARIES ${${otb-module}_LIBRARIES} +) diff --git a/app/otbSARDeramp.cxx b/app/otbSARDeramp.cxx new file mode 100644 index 0000000..3ff808c --- /dev/null +++ b/app/otbSARDeramp.cxx @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2005-2018 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbWrapperApplication.h" +#include "otbWrapperApplicationFactory.h" + +#include "otbSARDerampImageFilter.h" + +#include "otbWrapperOutputImageParameter.h" +#include "otbWrapperTypes.h" + +#include <iostream> +#include <string> +#include <fstream> + +namespace otb +{ + + namespace Wrapper + { + + class SARDeramp : public Application + { + public: + typedef SARDeramp Self; + typedef itk::SmartPointer<Self> Pointer; + + itkNewMacro(Self); + itkTypeMacro(SARDeramp, otb::Wrapper::Application); + + // Filter + typedef otb::SARDerampImageFilter<ComplexFloatImageType> DerampFilterType; + + private: + void DoInit() override + { + SetName("SARDeramp"); + SetDescription("Deramping/Reramping of S1 IW Burst."); + + SetDocName("SAR Deramp"); + SetDocLongDescription("This application does the deramping or reramping of S1 Iw burst."); + + //Optional descriptors + SetDocLimitations("Only Sentinel 1 products are supported for now."); + SetDocAuthors("OTB-Team"); + SetDocSeeAlso(" "); + AddDocTag(Tags::SAR); + + //Parameter declarations + AddParameter(ParameterType_ComplexInputImage, "in", "Input burst"); + SetParameterDescription("in", "Input burst (from S1 Iw product)."); + + AddParameter(ParameterType_ComplexOutputImage, "out", "Output burst"); + SetParameterDescription("out","Output burst (deramped or reramped)."); + + AddParameter(ParameterType_Bool, "reramp", "Activate Reramping mode"); + SetParameterDescription("reramp", "If true, then reramping else deramping."); + + AddRAMParameter(); + + SetDocExampleParameterValue("in","s1b-s4-slc-vv-20160929t014610-20160929t014634-002277-003d71-002.tiff"); + SetDocExampleParameterValue("out","s1a-s4-slc-vv-20160818t014650-20160818t014715-012648-013db1-002_Deramp.tiff"); + } + + + void DoUpdateParameters() override + { + // Nothing to do here : all parameters are independent + } + + void DoExecute() override + { + // Check if reramp is enabled + bool derampMode = true; + if (IsParameterEnabled("reramp")) + { + derampMode = false; + } + + if (derampMode) + { + otbAppLogINFO(<<"Deramp Mode"); + } + else + { + otbAppLogINFO(<<"Reramp Mode"); + } + + // Instanciate the Interferogram filter + DerampFilterType::Pointer filterDeramp = DerampFilterType::New(); + m_Ref.push_back(filterDeramp.GetPointer()); + filterDeramp->SetDerampMode(derampMode); + + // Pipeline + filterDeramp->SetInput(GetParameterComplexFloatImage("in")); + SetParameterComplexOutputImage("out", filterDeramp->GetOutput()); + + } + // Vector for filters + std::vector<itk::ProcessObject::Pointer> m_Ref; + + }; + + } + +} + + + +OTB_APPLICATION_EXPORT(otb::Wrapper::SARDeramp) diff --git a/include/otbSARDerampImageFilter.h b/include/otbSARDerampImageFilter.h index b10fa48..ff583a7 100644 --- a/include/otbSARDerampImageFilter.h +++ b/include/otbSARDerampImageFilter.h @@ -31,6 +31,24 @@ #include "otbImageKeywordlist.h" #include "otbSarSensorModelAdapter.h" +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-parameter" +# pragma GCC diagnostic ignored "-Woverloaded-virtual" +# pragma GCC diagnostic ignored "-Wshadow" +# include "ossim/ossimTimeUtilities.h" + +# pragma GCC diagnostic pop + +#else +# include "ossim/ossimTimeUtilities.h" +#endif + +#if defined(USE_BOOST_TIME) +# include <boost/date_time/posix_time/posix_time.hpp> +#include <ostream> +#endif + namespace otb { /** \class SARDerampImageFilter @@ -59,7 +77,7 @@ public: itkTypeMacro(SARDerampImageFilter,ImageToImageFilter); /** Typedef to image input/output type VectorImage (Complex Image) */ - typedef TImage ImageInType; + typedef TImage ImageType; /** Typedef to describe the inout image pointer type. */ typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::ConstPointer ImageConstPointer; @@ -83,8 +101,53 @@ public: // Typedef for iterators typedef itk::ImageScanlineConstIterator< ImageType > InputIterator; typedef itk::ImageScanlineIterator< ImageType > OutputIterator; + +#if defined(USE_BOOST_TIME) + typedef boost::posix_time::ptime TimeType; + typedef boost::posix_time::precise_duration DurationType; +#else + typedef ossimplugins::time::ModifiedJulianDate TimeType; + typedef ossimplugins::time::Duration DurationType; +#endif - // Setter + // Struture declaration + struct FMRateRecordType + { + TimeType azimuthFMRateTime; + double coef0FMRate; + double coef1FMRate; + double coef2FMRate; + double tau0FMRate; + friend std::ostream & operator<<(std::ostream & os, const FMRateRecordType & v) + { + return os << "{ azimuthFMRateTime: " << v.azimuthFMRateTime + << ", coefficient 0: " << v.coef0FMRate + << ", coefficient 1: " << v.coef1FMRate + << ",coefficient 2: " << v.coef2FMRate + << ",slant range time (tau 0): " << v.tau0FMRate + << "}"; +} +}; + + struct DCFRecordType + { + TimeType azimuthDCFTime; + double coef0DCF; + double coef1DCF; + double coef2DCF; + double tau0DCF; + friend std::ostream & operator<<(std::ostream & os, const DCFRecordType & v) + { + return os << "{ azimuthDCFTime: " << v.azimuthDCFTime + << ", coefficient 0: " << v.coef0DCF + << ", coefficient 1: " << v.coef1DCF + << ",coefficient 2: " << v.coef2DCF + << ",slant range time (tau 0): " << v.tau0DCF + << "}"; +} +}; + + // Setter itkSetMacro(DerampMode, bool); // Getter @@ -122,6 +185,12 @@ protected: void BeforeThreadedGenerateData() ITK_OVERRIDE; + void getAllCoefs(ImageKeywordlist const& kwl, std::vector<FMRateRecordType> & FMRateRecords); + void getAllCoefs(ImageKeywordlist const& kwl, std::vector<DCFRecordType> & DCFRecords); + +double applyFMRateCoefs(unsigned int index_sample); +double applyDCFCoefs(unsigned int index_sample); + private: SARDerampImageFilter(const Self&); // purposely not implemented void operator=(const Self &); // purposely not @@ -134,36 +203,40 @@ protected: bool m_DerampMode; // First azimuth/range time - float m_FirstAziTime, m_FirstRangeTime; + TimeType m_FirstAziTime; + double m_FirstRangeTime; // Mid burst zero Doppler azimuth time [s] - float m_MidAziTime; + TimeType m_MidAziTime; // Spacecraft velocity computed at mid-burst time (m_MidAziTime) [m/s] - float m_VSatAtMidAziTime; + double m_VSatAtMidAziTime; // Doppler Centroid rate introduced by the scanning og the antenna [Hz/s] - float m_Ks; + double m_Ks; // Azimuth time interval [s] - float m_AziTimeInt; + double m_AziTimeInt; // Range sampling rate [Hz] - float m_RangeSamplingRate; + double m_RangeSamplingRate; // Parameters coefficients for Doppler FM Rate - float m_FM_C0, m_FM_C1, m_FM_C2, m_FM_Tau0; + double m_FM_C0, m_FM_C1, m_FM_C2, m_FM_Tau0; // Parameters coefficients for Doppler Centroid Frequency - float m_DCF_C0, m_DCF_C1, m_DCF_C2, m_DCF_Tau0; + double m_DCF_C0, m_DCF_C1, m_DCF_C2, m_DCF_Tau0; // Reference time 0 [s] - float m_RefTime0; + double m_RefTime0; + + // Mid Line Burst + double m_LineAtMidBurst; // First estimation bool m_FirstEstimation; - const double C; + const double C = 299792458; }; } // End namespace otb diff --git a/include/otbSARDerampImageFilter.txx b/include/otbSARDerampImageFilter.txx index 709089c..fcf4204 100644 --- a/include/otbSARDerampImageFilter.txx +++ b/include/otbSARDerampImageFilter.txx @@ -34,6 +34,20 @@ #include <algorithm> #include <omp.h> +#if defined(USE_BOOST_TIME) +using boost::posix_time::microseconds; +using boost::posix_time::seconds; +#else +using ossimplugins::time::microseconds; +using ossimplugins::time::seconds; +#endif + +#ifndef M_1_PI +#define M_1_PI 0.31830988618379067154 +#endif + + + namespace otb { /** @@ -43,9 +57,9 @@ namespace otb SARDerampImageFilter< TImage >::SARDerampImageFilter() : m_DerampMode(true), m_FirstAziTime(0), m_FirstRangeTime(0), m_MidAziTime(0), m_VSatAtMidAziTime(0), m_Ks(0), m_AziTimeInt(0),m_RangeSamplingRate(0), m_FM_C0(0), m_FM_C1(0), m_FM_C2(0), m_FM_Tau0(0), - m_DCF_C0(0), m_DCF_C1(0), m_DCF_C2(0), m_DCF_Tau0(0), m_RefTime0(0), m_FirstEstimation(false) + m_DCF_C0(0), m_DCF_C1(0), m_DCF_C2(0), m_DCF_Tau0(0), m_RefTime0(0), m_FirstEstimation(true) { -C = 299792458; + } /** @@ -54,6 +68,7 @@ C = 299792458; template <class TImage> SARDerampImageFilter< TImage >::~SARDerampImageFilter() { + } /** @@ -70,6 +85,66 @@ C = 299792458; << std::endl; } + template<class TImage> + void + SARDerampImageFilter< TImage > + ::getAllCoefs(ImageKeywordlist const& kwl, std::vector<FMRateRecordType> & FMRateRecords) + { + char fmRatePrefix_[1024]; + std::size_t nbLists(0); + + nbLists = std::stoi(kwl.GetMetadataByKey("azimuthFmRate.azi_fm_rate_coef_nb_list")); + + std::string FM_PREFIX = "azimuthFmRate.azi_fm_rate_coef_list"; + + for (std::size_t listId=0; listId!= nbLists ; ++listId) + { + const int pos = sprintf(fmRatePrefix_, "%s%d.", FM_PREFIX.c_str(), (listId+1)); + assert(pos > 0 && pos < sizeof(fmRatePrefix_)); + const std::string FMPrefix(fmRatePrefix_, pos); + + FMRateRecordType fmRateRecord; + fmRateRecord.azimuthFMRateTime = ossimplugins::time::toModifiedJulianDate(kwl.GetMetadataByKey(FMPrefix+ + "azi_fm_rate_coef_time")); + fmRateRecord.coef0FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "1.azi_fm_rate_coef")); + fmRateRecord.coef1FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "2.azi_fm_rate_coef")); + fmRateRecord.coef2FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "3.azi_fm_rate_coef")); + fmRateRecord.tau0FMRate = std::stod(kwl.GetMetadataByKey(FMPrefix + "slant_range_time")); + + FMRateRecords.push_back(fmRateRecord); + } + } + + template<class TImage> + void + SARDerampImageFilter< TImage > + ::getAllCoefs(ImageKeywordlist const& kwl, std::vector<DCFRecordType> & DCFRecords) + { + char dcfPrefix_[1024]; + std::size_t nbLists(0); + + nbLists = std::stoi(kwl.GetMetadataByKey("dopplerCentroid.dop_coef_nb_list")); + + std::string DCF_PREFIX = "dopplerCentroid.dop_coef_list"; + + for (std::size_t listId=0; listId!= nbLists ; ++listId) + { + const int pos = sprintf(dcfPrefix_, "%s%d.", DCF_PREFIX.c_str(), (listId+1)); + assert(pos > 0 && pos < sizeof(dcfPrefix_)); + const std::string DCFPrefix(dcfPrefix_, pos); + + DCFRecordType dcfRecord; + dcfRecord.azimuthDCFTime = ossimplugins::time::toModifiedJulianDate(kwl.GetMetadataByKey(DCFPrefix + + "dop_coef_time")); + dcfRecord.coef0DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "1.dop_coef")); + dcfRecord.coef1DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "2.dop_coef")); + dcfRecord.coef2DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "3.dop_coef")); + dcfRecord.tau0DCF = std::stod(kwl.GetMetadataByKey(DCFPrefix + "slant_range_time")); + + DCFRecords.push_back(dcfRecord); + } + } + /** * Method selectFMRateCoef */ @@ -78,7 +153,49 @@ C = 299792458; SARDerampImageFilter< TImage > ::selectFMRateCoef() { + // Get input + ImagePointer inputPtr = const_cast< ImageType * >( this->GetInput() ); + + // Retrieve all polynomials + std::vector<FMRateRecordType> FMRateRecords; + this->getAllCoefs(inputPtr->GetImageKeywordlist(), FMRateRecords); + + DurationType diffAziTimeMin; + unsigned int polySelected = 0; + + // Select one polynomial (with m_MidAziTime) + for (unsigned int i = 0; i < FMRateRecords.size(); i++) + { + // Difference between midAziTime and aziTime of the current polynomial + DurationType diffAziTime; + if (m_MidAziTime > FMRateRecords[i].azimuthFMRateTime) + { + diffAziTime = DurationType(m_MidAziTime - FMRateRecords[i].azimuthFMRateTime); + } + else + { + diffAziTime = DurationType(FMRateRecords[i].azimuthFMRateTime - m_MidAziTime); + } + + if (diffAziTime < diffAziTimeMin || i == 0) + { + diffAziTimeMin = diffAziTime; + polySelected = i; + } + } + + // Assign m_FM_C0, m_FM_C1, m_FM_C2, m_FM_Tau0 + m_FM_C0 = FMRateRecords[polySelected].coef0FMRate; + m_FM_C1 = FMRateRecords[polySelected].coef1FMRate; + m_FM_C2 = FMRateRecords[polySelected].coef2FMRate; + m_FM_Tau0 = FMRateRecords[polySelected].tau0FMRate; + + std::cout << "m_FM_C0 = " << m_FM_C0 << std::endl; + std::cout << "m_FM_C1 = " << m_FM_C1 << std::endl; + std::cout << "m_FM_C2 = " << m_FM_C2 << std::endl; + std::cout << "m_FM_Tau0 = " << m_FM_Tau0 << std::endl; + return true; } /** @@ -89,7 +206,77 @@ C = 299792458; SARDerampImageFilter< TImage > ::selectDCFCoef() { + // Get input + ImagePointer inputPtr = const_cast< ImageType * >( this->GetInput() ); + + // Retrieve all polynomials + std::vector<DCFRecordType> DCFRecords; + this->getAllCoefs(inputPtr->GetImageKeywordlist(), DCFRecords); + + DurationType diffAziTimeMin; + unsigned int polySelected = 0; + // Select one polynomial (with m_MidAziTime) + for (unsigned int i = 0; i < DCFRecords.size(); i++) + { + // Difference between midAziTime and aziTime of the current polynomial + DurationType diffAziTime; + if (m_MidAziTime > DCFRecords[i].azimuthDCFTime) + { + diffAziTime = DurationType(m_MidAziTime - DCFRecords[i].azimuthDCFTime); + } + else + { + diffAziTime = DurationType(DCFRecords[i].azimuthDCFTime - m_MidAziTime); + } + + if (diffAziTime < diffAziTimeMin || i == 0) + { + diffAziTimeMin = diffAziTime; + polySelected = i; + } + } + + // Assign m_FM_C0, m_FM_C1, m_FM_C2, m_FM_Tau0 + m_DCF_C0 = DCFRecords[polySelected].coef0DCF; + m_DCF_C1 = DCFRecords[polySelected].coef1DCF; + m_DCF_C2 = DCFRecords[polySelected].coef2DCF; + m_DCF_Tau0 = DCFRecords[polySelected].tau0DCF; + + std::cout << "m_DCF_C0 = " << m_DCF_C0 << std::endl; + std::cout << "m_DCF_C1 = " << m_DCF_C1 << std::endl; + std::cout << "m_DCF_C2 = " << m_DCF_C2 << std::endl; + std::cout << "m_DCF_Tau0 = " << m_DCF_Tau0 << std::endl; + + return true; + } + + /** + * Apply FM Rate coefficients Method + */ + template<class TImage> + double + SARDerampImageFilter<TImage> + ::applyFMRateCoefs(unsigned int index_sample) + { + double slant_range_time = m_FirstRangeTime + (index_sample / m_RangeSamplingRate); + + return (m_FM_C0 + m_FM_C1*(slant_range_time - m_FM_Tau0) + m_FM_C2*(slant_range_time - m_FM_Tau0)* + (slant_range_time - m_FM_Tau0)); + } + + /** + * Apply doppler centroid Frequency coefficients Method + */ + template<class TImage> + double + SARDerampImageFilter<TImage> + ::applyDCFCoefs(unsigned int index_sample) + { + double slant_range_time = m_FirstRangeTime + (index_sample / m_RangeSamplingRate); + + return (m_DCF_C0 + m_DCF_C1*(slant_range_time - m_DCF_Tau0) + m_DCF_C2*(slant_range_time - m_DCF_Tau0)* + (slant_range_time - m_DCF_Tau0)); } /** @@ -111,30 +298,30 @@ C = 299792458; ImageKeywordlist inputKWL = inputPtr->GetImageKeywordlist(); // Check version of header/kwl (at least 3) - int headerVersion = std::stoi(inputKLW.GetMetadataByKey("header.version")); + int headerVersion = std::stoi(inputKWL.GetMetadataByKey("header.version")); if (headerVersion < 3) { - itkExceptionMacro(<<"Header version is < 3. Please Upgrade your geom file"); + itkExceptionMacro(<<"Header version is inferior to 3. Please Upgrade your geom file"); } // Get some metadata - float aziSteeringRate = std::stof(inputKLW.GetMetadataByKey("support_data.azimuth_steering_rate")); + double aziSteeringRate = std::stod(inputKWL.GetMetadataByKey("support_data.azimuth_steering_rate")); // Conversion to radians per seconds - aziSteeringRate *= (M_PI/180); + aziSteeringRate *= (M_1_PI/180); - m_FirstAziTime = std::stof(inputKLW.GetMetadataByKey("support_data.first_line_time")); - m_FirstRangeTime = std::stof(inputKLW.GetMetadataByKey("support_data.slant_range_to_first_pixel")); + m_FirstAziTime = ossimplugins::time::toModifiedJulianDate((inputKWL.GetMetadataByKey("support_data.first_line_time"))); + m_FirstRangeTime = std::stod(inputKWL.GetMetadataByKey("support_data.slant_range_to_first_pixel")); - m_AziTimeInt = std::stof(inputKLW.GetMetadataByKey("support_data.line_time_interval")); - m_RangeTimeInt = std::stof(inputKLW.GetMetadataByKey("support_data.range_sampling_rate")); + m_AziTimeInt = std::stod(inputKWL.GetMetadataByKey("support_data.line_time_interval")); + m_RangeSamplingRate = std::stod(inputKWL.GetMetadataByKey("support_data.range_sampling_rate")); - float radarFrequency = std::stof(inputKLW.GetMetadataByKey("support_data.radar_frequency")); + double radarFrequency = std::stod(inputKWL.GetMetadataByKey("support_data.radar_frequency")); - int nbLineBurst = std::stof(inputKLW.GetMetadataByKey("support_data.geom.bursts.number_lines_per_burst")); + int nbLineBurst = std::stod(inputKWL.GetMetadataByKey("support_data.geom.bursts.number_lines_per_burst")); // Estimation m_Ks - double lineAtMidBurst = nbLineBurst/2.; - m_MidAziTime = m_FirstAziTime + m_AziTimeInt * lineAtMidBurst; + m_LineAtMidBurst = nbLineBurst/2.; + m_MidAziTime = m_FirstAziTime + seconds(m_AziTimeInt * m_LineAtMidBurst); // Try to create a SarSensorModelAdapter SarSensorModelAdapter::Pointer sarSensorModel = SarSensorModelAdapter::New(); @@ -145,7 +332,7 @@ C = 299792458; Point3DType satpos, satvel; - bool lineToSatPosAndVelOk = sarSensorModel->LineToSatPositionAndVelocity(lineAtMidBurst, satpos, satvel); + bool lineToSatPosAndVelOk = sarSensorModel->LineToSatPositionAndVelocity(m_LineAtMidBurst, satpos, satvel); if (!lineToSatPosAndVelOk) itkExceptionMacro(<<"Failed to estimate satellite position and velocity."); @@ -154,8 +341,17 @@ C = 299792458; m_Ks = (2*m_VSatAtMidAziTime/C) * radarFrequency * aziSteeringRate; + std::cout << "m_FirstAziTime = " << m_FirstAziTime << std::endl; + std::cout << "m_MidAziTime = " << m_MidAziTime << std::endl; + // Polynomial selection (FM Rate and Doppler Centroid Frequency) - + this->selectFMRateCoef(); + this->selectDCFCoef(); + + // Estimate Reference time at first sample + m_RefTime0 = - (this->applyDCFCoefs(0) / this->applyFMRateCoefs(0)); + + std::cout << "m_RefTime0 = " << m_RefTime0 << std::endl; } } @@ -166,168 +362,65 @@ C = 299792458; template<class TImage> void SARDerampImageFilter<TImage> - ::ThreadedGenerateData(const ImageOutRegionType & outputRegionForThread, + ::ThreadedGenerateData(const ImageRegionType & outputRegionForThread, itk::ThreadIdType /*threadId*/) { // Compute corresponding input region for master and slave cartesian mean - ImageInRegionType inputMasterRegionForThread = outputRegionForThread; - - // Compute corresponding input region for grid - GridRegionType inputGridRegionForThread = OutputRegionToInputGridRegion(outputRegionForThread); + ImageRegionType inputRegionForThread = outputRegionForThread; // Iterator on output OutputIterator OutIt(this->GetOutput(), outputRegionForThread); OutIt.GoToBegin(); - // Iterator on input master cartesian mean - InputIterator InMasterCartMeanIt(this->GetMasterCartesianMeanInput(), inputMasterRegionForThread); - InMasterCartMeanIt.GoToBegin(); - - // Allocate output pixel - ImageOutPixelType pixelOut; - if (m_MasterCopy) - { - pixelOut.Reserve(5); - } - else - { - pixelOut.Reserve(2); - } - - double constMul = static_cast<double>(m_Factor*2*M_PI)/m_Lambda; - - if (m_ApproxDiapason) - { - constMul = static_cast<double>(m_Factor*256)/m_Lambda; - } - - Point3DType worldSlave; - Point3DType satPosSlave; - Point3DType satVelSlave; - Point3DType worldMaster; - Point3DType satPosMaster; - Point3DType satVelMaster; + // Iterator on input + InputIterator InIt(this->GetInput(), inputRegionForThread); + InIt.GoToBegin(); // For each line - while (!OutIt.IsAtEnd() && !InMasterCartMeanIt.IsAtEnd()) + while (!OutIt.IsAtEnd() && !InIt.IsAtEnd()) { OutIt.GoToBeginOfLine(); - InMasterCartMeanIt.GoToBeginOfLine(); - - // Index of current line (into output Geometry) - int ind_Line = OutIt.GetIndex()[1] + int(this->GetOutput()->GetOrigin()[1]); - - // Get Master Cartesian Mean Per line - ImageInIndexType indexMasterPerLine; - indexMasterPerLine[0] = 0; // Always 0 since Master/Slave Cartesain Per Line are vectors - indexMasterPerLine[1] = ind_Line; - + InIt.GoToBeginOfLine(); - // Get the index of current tile into grid to retrive the shifts (the closest (round) grid point - // at the center of current tile). Output Geo = Master Cart Mean Geo = (Grid geo / GridStep) - int Lgrid = std::round( ind_Line / m_GridStep[1]); - - Lgrid = std::min (std::max (Lgrid, 0), - static_cast<int>(this->GetGridInput()->GetLargestPossibleRegion().GetSize()[1])-1); - - GridIndexType gridIndex; - gridIndex[0] = 0; - gridIndex[1] = Lgrid; - - double gridShift_Azi = this->GetGridInput()->GetPixel(gridIndex)[1]; + // Output index + ImageIndexType index = OutIt.GetIndex(); - // Apply on slave, the integer shifts - int Le = std::round(ind_Line + gridShift_Azi); - - // Get Slave Cartesian Means - ImageInIndexType indexSlavePerLine; - indexSlavePerLine[0] = 0; // Always 0 since Master/Slave Cartesain Per Line are vectors - indexSlavePerLine[1] = Le; + // Zero Doppler azimuth Time + double aziTime = (index[1]-m_LineAtMidBurst)*m_AziTimeInt; + + // For each colunm + while (!OutIt.IsAtEndOfLine() && !InIt.IsAtEndOfLine()) + { + // Reference Time + double refTime = - (this->applyDCFCoefs(index[0]) / this->applyFMRateCoefs(index[0])) - m_RefTime0; - ////////// Estimate satellite positions for the current line ////////// - bool checkSlave = m_SarSensorModelAdapterForSlave->LineToSatPositionAndVelocity(static_cast<double>(Le), satPosSlave, - satVelSlave); + // Kt + double Kt = (this->applyFMRateCoefs(index[0]) * m_Ks) / (this->applyFMRateCoefs(index[0]) - m_Ks); - bool checkMaster = m_SarSensorModelAdapterForMaster->LineToSatPositionAndVelocity(static_cast<double>(ind_Line), - satPosMaster, satVelMaster); + // Phi + double Phi = - M_1_PI * Kt * (aziTime -refTime)*(aziTime -refTime); - // For each colunm - while (!OutIt.IsAtEndOfLine() && !InMasterCartMeanIt.IsAtEndOfLine()) - { - // Check slave Index - if (checkSlave) + // Deramping or Reramping + if (!m_DerampMode) { - // Check if Value into Master Cartesian Mean with IsData Mask - if (InMasterCartMeanIt.Get()[3] != 0) - { - float Xcart_Ground = InMasterCartMeanIt.Get()[0]; - float Ycart_Ground = InMasterCartMeanIt.Get()[1]; - float Zcart_Ground = InMasterCartMeanIt.Get()[2]; - - //////////// Estimate Topographic phase (P = (factor*256/lambda) * (De-Dm)) ////////// - double De = sqrt(pow((Xcart_Ground - satPosSlave[0]), 2) + - pow((Ycart_Ground - satPosSlave[1]), 2) + - pow((Zcart_Ground - satPosSlave[2]), 2)); - - double Dm = sqrt(pow((Xcart_Ground - satPosMaster[0]), 2) + - pow((Ycart_Ground - satPosMaster[1]), 2) + - pow((Zcart_Ground - satPosMaster[2]), 2)); - - - pixelOut[0] = constMul * (De-Dm); - // Mod 2*Pi - //pixelOut[0] = pixelOut[0]-(2*M_PI)*floor(pixelOut[0]/(2*M_PI)); - - // IsData set to 1 - pixelOut[1] = 1; - - if (m_MasterCopy) - { - ////////////// Copy of Master Cartesian Mean ////////////// - pixelOut[2] = Xcart_Ground; - pixelOut[3] = Ycart_Ground; - pixelOut[4] = Zcart_Ground; - } - - } - else - { - // All components set to 0 - pixelOut[0] = 0; - pixelOut[1] = 0; - if (m_MasterCopy) - { - pixelOut[2] = 0; - pixelOut[3] = 0; - pixelOut[4] = 0; - } - } - + Phi *= -1; } - else - { - // All components set to 0 - pixelOut[0] = 0; - pixelOut[1] = 0; - if (m_MasterCopy) - { - pixelOut[2] = 0; - pixelOut[3] = 0; - pixelOut[4] = 0; - } - } + ImagePixelType outPixel; // Complex + outPixel.real((InIt.Get().real() * std::cos(Phi)) - (InIt.Get().imag() * std::sin(Phi))); + outPixel.imag((InIt.Get().real() * std::sin(Phi)) + (InIt.Get().imag() * std::cos(Phi))); + //////////// Assign Output //////////// - OutIt.Set(pixelOut); + OutIt.Set(outPixel); // Increment iterators ++OutIt; - ++InMasterCartMeanIt; + ++InIt; } // End colunms (ouput) // Next Line OutIt.NextLine(); - InMasterCartMeanIt.NextLine(); + InIt.NextLine(); } // End lines (ouput) } -- GitLab