From 34ec7d648046ea636d126c879a06fab023982fb5 Mon Sep 17 00:00:00 2001 From: Thomas Feuvrier <thomas.feuvrier@c-s.fr> Date: Thu, 29 Nov 2007 17:31:04 +0000 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20classe=20SIXSTraits=20avec=20?= =?UTF-8?q?la=20m=C3=A9thode=20principale=20qui=20appelle=20S=20pour=20cal?= =?UTF-8?q?culer=20les=20parametres=20de=20correction=20atmospherique.=20L?= =?UTF-8?q?a=20classe=20FilterFunctionValues=20(dans=20AtmosphericCorrecti?= =?UTF-8?q?onParameters.h)=20a=20=C3=A9t=C3=A9=20mise=20a=20jour=20:=20ajo?= =?UTF-8?q?ut=20d'un=20vector=20contenant=20la=20liste=20des=20longueurs?= =?UTF-8?q?=20interpol=C3=A9es=20si=20besoin=20au=20pas=20de=200.0025.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otbAtmosphericCorrectionParameters.cxx | 3 +- .../otbAtmosphericCorrectionParameters.h | 40 ++-- Code/Radiometry/otbSIXSTraits.cxx | 191 ++++++++++++++++++ Code/Radiometry/otbSIXSTraits.h | 77 +++++++ 4 files changed, 297 insertions(+), 14 deletions(-) create mode 100644 Code/Radiometry/otbSIXSTraits.cxx create mode 100644 Code/Radiometry/otbSIXSTraits.h diff --git a/Code/Radiometry/otbAtmosphericCorrectionParameters.cxx b/Code/Radiometry/otbAtmosphericCorrectionParameters.cxx index 89f5512209..fca8b9a81e 100644 --- a/Code/Radiometry/otbAtmosphericCorrectionParameters.cxx +++ b/Code/Radiometry/otbAtmosphericCorrectionParameters.cxx @@ -32,6 +32,7 @@ namespace otb /** Check the correpondance between the vector value size and the interval number between min and max.*/ /** return true if the vector step is not at 2.5 and the vector has been changed. */ +/* bool FilterFunctionValues :: SetParameters(const WavelenghtSpectralBandType L_min, const WavelenghtSpectralBandType L_max, const WavelenghtSpectralBandType step, const ValuesVectorType & vect) @@ -79,7 +80,7 @@ namespace otb } return hasChangedVector; } - +*/ /**PrintSelf method */ void FilterFunctionValues diff --git a/Code/Radiometry/otbAtmosphericCorrectionParameters.h b/Code/Radiometry/otbAtmosphericCorrectionParameters.h index 437d76cb39..965d18d23a 100644 --- a/Code/Radiometry/otbAtmosphericCorrectionParameters.h +++ b/Code/Radiometry/otbAtmosphericCorrectionParameters.h @@ -51,18 +51,40 @@ namespace otb typedef float WavelenghtSpectralBandType; typedef std::vector<WavelenghtSpectralBandType> ValuesVectorType; + /** Set vector that contains the filter function value. */ + void SetFilterFunctionValues(const ValuesVectorType & vect) + { + m_FilterFunctionValues = vect; + this->Modified(); + }; /** Get vector that contains the filter function value. */ const ValuesVectorType & GetFilterFunctionValues() const { return m_FilterFunctionValues; }; + /** Get vector that contains the filter function value 6S. */ + void SetFilterFunctionValues6S(const ValuesVectorType & vect) + { + m_FilterFunctionValues6S = vect; + this->Modified(); + }; + /** Get vector that contains the filter function value 6S. */ + const ValuesVectorType & GetFilterFunctionValues6S() const { return m_FilterFunctionValues6S; }; + + /** Set minimum spectral value. */ + itkSetMacro(MinSpectralValue,WavelenghtSpectralBandType); /** Get minimum spectral value. */ itkGetMacro(MinSpectralValue,WavelenghtSpectralBandType); + /** Set maximum spectral value. This value is automatically computed.*/ + itkSetMacro(MaxSpectralValue,WavelenghtSpectralBandType); /** Get maximum spectral value. This value is automatically computed.*/ itkGetMacro(MaxSpectralValue,WavelenghtSpectralBandType); + /** Set user step between each wavelenght spectral band values. */ + itkSetMacro(UserStep,WavelenghtSpectralBandType); /** Get user step between each wavelenght spectral band values. */ itkGetMacro(UserStep,WavelenghtSpectralBandType); /** Get the 6S imposed step : 2.5nm. */ itkGetConstMacro(StepOfWavelenghtSpectralBandValues, WavelenghtSpectralBandType); + /** Set paramaters and check value step. If it's not 2.5nm (cf. 6S), interpolate needed values.*/ - bool SetParameters(const WavelenghtSpectralBandType L_min, const WavelenghtSpectralBandType L_max, const WavelenghtSpectralBandType step, const ValuesVectorType & vect); +// bool SetParameters(const WavelenghtSpectralBandType L_min, const WavelenghtSpectralBandType L_max, const WavelenghtSpectralBandType step, const ValuesVectorType & vect); protected: @@ -79,21 +101,13 @@ namespace otb FilterFunctionValues(const Self&) ; //purposely not implemented void operator=(const Self&) ; //purposely not implemented - /** Set vector that contains the filter function value. */ - void SetFilterFunctionValues(ValuesVectorType vect) - { - m_FilterFunctionValues = vect; - this->Modified(); - }; - /** Set minimum spectral value. */ - itkSetMacro(MinSpectralValue,WavelenghtSpectralBandType); - /** Set maximum spectral value. This value is automatically computed.*/ - itkSetMacro(MaxSpectralValue,WavelenghtSpectralBandType); - /** Set user step between each wavelenght spectral band values. */ - itkSetMacro(UserStep,WavelenghtSpectralBandType); /** Vector that contains the filter function value. */ ValuesVectorType m_FilterFunctionValues; + /** Vector that contains the filter function value in 6S format (step of 0.0025). + * There values a computed by 6S. If the UserStep is 0.0025, then m_FilterFunctionValues is identical as m_FilterFunctionValues6S + */ + ValuesVectorType m_FilterFunctionValues6S; /** Minimum spectral value (in nm). */ WavelenghtSpectralBandType m_MinSpectralValue; /** Maximum spectral value (in nm). */ diff --git a/Code/Radiometry/otbSIXSTraits.cxx b/Code/Radiometry/otbSIXSTraits.cxx new file mode 100644 index 0000000000..071158ecb8 --- /dev/null +++ b/Code/Radiometry/otbSIXSTraits.cxx @@ -0,0 +1,191 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "otbSIXSTraits.h" + +#include "otb_6S.h" +#include "main_6s.h" +#include "otbMacro.h" + +namespace otb +{ + + +void +SIXSTraits::ComputeAtmosphericParameters( + const double SolarZenithalAngle, /** The Solar zenithal angle */ + const double SolarAzimutalAngle, /** The Solar azimutal angle */ + const double ViewingZenithalAngle, /** The Viewing zenithal angle */ + const double ViewingAzimutalAngle, /** The Viewing azimutal angle */ + const unsigned int Month, /** The Month */ + const unsigned int Day, /** The Day (in the month) */ + const double AtmosphericPressure, /** The Atmospheric pressure */ + const double WaterVaporAmount, /** The Water vapor amount (Total water vapor content over vertical atmospheric column) */ + const double OzoneAmount, /** The Ozone amount (Stratospheric ozone layer content) */ + const AerosolModelType & AerosolModel, /** The Aerosol model */ + const double AerosolOptical, /** The Aerosol optical (radiative impact of aerosol for the reference wavelenght 550-nm) */ + WavelenghtSpectralType& WavelenghtSpectralBand, /** Wavelenght for the spectral band definition */ + /** Note : The Max wavelenght spectral band value must be updated ! */ + double & AtmosphericReflectance, /** Atmospheric reflectance */ + double & AtmosphericSphericalAlbedo, /** atmospheric spherical albedo */ + double & TotalGaseousTransmission, /** Total gaseous transmission */ + double & DownwardTransmittance, /** downward transmittance */ + double & UpwardTransmittance /** upward transmittance */ + ) +{ +// geometrical conditions + otb_6s_real asol(static_cast<otb_6s_real>(SolarZenithalAngle)); + otb_6s_real phi0(static_cast<otb_6s_real>(SolarAzimutalAngle)); + otb_6s_real avis(static_cast<otb_6s_real>(ViewingZenithalAngle)); + otb_6s_real phiv(static_cast<otb_6s_real>(ViewingAzimutalAngle)); + otb_6s_integer month(static_cast<otb_6s_integer>(Month)); + otb_6s_integer jday(static_cast<otb_6s_integer>(Day)); + otb_6s_real pressure(static_cast<otb_6s_real>(AtmosphericPressure)); + otb_6s_real uw(static_cast<otb_6s_real>(WaterVaporAmount)); + otb_6s_real uo3(static_cast<otb_6s_real>(OzoneAmount)); +// atmospheric model + otb_6s_integer iaer(static_cast<otb_6s_integer>(AerosolModel)); + otb_6s_real taer55(static_cast<otb_6s_real>(AerosolOptical)); + + + // Init output parameters + AtmosphericReflectance = 0.; + AtmosphericSphericalAlbedo = 0.; + TotalGaseousTransmission = 0.; + DownwardTransmittance = 0.; + UpwardTransmittance = 0.; + + otb_6s_real wlinf(0.), wlsup(0.); + otb_6s_real otb_ratm__(0.), sast(0.), tgasm(0.), sdtott(0.), sutott(0.); + try + { + // 6S official Wavelenght Spectral Band step value + const double SIXSStepOfWavelenghtSpectralBandValues = .0025; + // Generate 6s Wavelenght Spectral Band with the offcicial step value + ComputeWavelenghtSpectralBandValuesFor6S( SIXSStepOfWavelenghtSpectralBandValues, + WavelenghtSpectralBand // Update + ); + + // 6S official tab size Wavelenght Spectral + const unsigned int S_6S_SIZE=1501; + // Generate WavelenghtSpectralBand in 6S compatible buffer s[1501] + otb_6s_integer iinf = static_cast<otb_6s_integer>((WavelenghtSpectralBand.GetMinSpectralValue() - (double).25) / SIXSStepOfWavelenghtSpectralBandValues + (double)1.5); + otb_6s_integer isup = static_cast<otb_6s_integer>((WavelenghtSpectralBand.GetMaxSpectralValue() - (double).25) / SIXSStepOfWavelenghtSpectralBandValues + (double)1.5); + + otb_6s_integer cpt=iinf-1; + otb_6s_real * s(NULL); + s = new otb_6s_real[S_6S_SIZE]; + memset( s, 0, S_6S_SIZE*sizeof(otb_6s_real) ); + const ValuesVectorType & FilterFunctionValues6S = WavelenghtSpectralBand.GetFilterFunctionValues6S(); + // Set the values of FilterFunctionValues6S in s between [iinf-1;isup] + for(unsigned int i=0 ; cpt<isup ; i++) + { + s[cpt] = FilterFunctionValues6S[i]; + cpt++; + } + // Call 6s main function + otbMsgDevMacro(<< "Start call 6S main function ..."); + otb_6s_ssssss_otb_main_function( &asol, &phi0, &avis, &phiv, &month, &jday, + &pressure, &uw, &uo3, + &iaer, + &taer55, + &wlinf, &wlsup, + s, + &otb_ratm__, + &sast, + &tgasm, + &sdtott, + &sutott); + otbMsgDevMacro(<< "Done call 6S main function!"); + delete [] s; + s = NULL; + } + catch( std::bad_alloc & err ) + { + itkGenericExceptionMacro( <<"Exception bad_alloc in SIXSTraits class: "<<(char*)err.what()); + } + catch (...) + { + itkGenericExceptionMacro( <<"Unknown exception in SIXSTraits class (catch(...)"); + } + + // Set outputs parameters + AtmosphericReflectance = static_cast<double>(otb_ratm__); + AtmosphericSphericalAlbedo = static_cast<double>(sast); + TotalGaseousTransmission = static_cast<double>(tgasm); + DownwardTransmittance = static_cast<double>(sdtott); + UpwardTransmittance = static_cast<double>(sutott); +} + + +void +SIXSTraits::ComputeWavelenghtSpectralBandValuesFor6S( + const double SIXSStepOfWavelenghtSpectralBandValues, + WavelenghtSpectralType& WavelenghtSpectralBand + ) +{ + const double L_min = static_cast<double>(WavelenghtSpectralBand.GetMinSpectralValue()); + const double L_max = static_cast<double>(WavelenghtSpectralBand.GetMaxSpectralValue()); + const double L_userStep = static_cast<double>(WavelenghtSpectralBand.GetUserStep()); + const ValuesVectorType & FilterFunctionValues = WavelenghtSpectralBand.GetFilterFunctionValues(); + unsigned int i = 1; + unsigned int j = 1; + const double invStep = static_cast<double>(1./L_userStep); + double value(0.); + + // Generate WavelenghtSpectralBand if the step is not the offical 6S step value + if( vcl_abs(L_userStep-SIXSStepOfWavelenghtSpectralBandValues) > .00000001 ) + { + ValuesVectorType values(1, FilterFunctionValues[0]); //vector size 1 with the value vect[0] + + // Stop the interpolation at the max spectral value. + value = i*SIXSStepOfWavelenghtSpectralBandValues; + while(L_min+value <= L_max ) + { + // Search the User interval that surround the StepOfWavelenghtSpectralBandValues current value. + + while(j*L_userStep <= value) + { + j++; + } + double valueTemp; + valueTemp = static_cast<double>(FilterFunctionValues[j-1]) + + ((static_cast<double>(FilterFunctionValues[j])-static_cast<double>(FilterFunctionValues[j-1]))*invStep) + *(value-L_userStep*(j-1)); + values.push_back(static_cast<WavelenghtSpectralBandType>(valueTemp)); + + i++; + } + + if (L_min+(i-1)*SIXSStepOfWavelenghtSpectralBandValues != L_max) + { + values.push_back(0); + } + // Store this values + WavelenghtSpectralBand.SetFilterFunctionValues6S(values); + // Store the new Max MaxSpectralValue + WavelenghtSpectralBand.SetMaxSpectralValue(static_cast<WavelenghtSpectralBandType>(L_min + i*SIXSStepOfWavelenghtSpectralBandValues)); + + } + else + { + // Init with copy of FilterFunctionValues input vector values + WavelenghtSpectralBand.SetFilterFunctionValues6S(FilterFunctionValues); + } +} + +} // namespace otb diff --git a/Code/Radiometry/otbSIXSTraits.h b/Code/Radiometry/otbSIXSTraits.h new file mode 100644 index 0000000000..4ac67b97c5 --- /dev/null +++ b/Code/Radiometry/otbSIXSTraits.h @@ -0,0 +1,77 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef _otbSIXSTraits_h +#define _otbSIXSTraits_h + +#include "otbAtmosphericCorrectionParameters.h" + +namespace otb +{ + + +/** \class SIXSTraits + * \brief SIXSTraits operations. + * + * Call 6S main function. The main method call 6S to calculate atmospheric correction parameters. + * It use by the OTB Atmospheric correction framework. + * + */ +class ITK_EXPORT SIXSTraits +{ +public: + + /** Standard class typedefs. */ + typedef SIXSTraits Self; + + typedef FilterFunctionValues WavelenghtSpectralType; + typedef AtmosphericCorrectionParameters::AerosolModelType AerosolModelType; + typedef WavelenghtSpectralType::WavelenghtSpectralBandType WavelenghtSpectralBandType; + typedef WavelenghtSpectralType::ValuesVectorType ValuesVectorType; + + /** Call 6S main function */ + static void ComputeAtmosphericParameters( + const double SolarZenithalAngle, /** The Solar zenithal angle */ + const double SolarAzimutalAngle, /** The Solar azimutal angle */ + const double ViewingZenithalAngle, /** The Viewing zenithal angle */ + const double ViewingAzimutalAngle, /** The Viewing azimutal angle */ + const unsigned int Month, /** The Month */ + const unsigned int Day, /** The Day (in the month) */ + const double AtmosphericPressure, /** The Atmospheric pressure */ + const double WaterVaporAmount, /** The Water vapor amount (Total water vapor content over vertical atmospheric column) */ + const double OzoneAmount, /** The Ozone amount (Stratospheric ozone layer content) */ + const AerosolModelType & AerosolModel, /** The Aerosol model */ + const double AerosolOptical, /** The Aerosol optical (radiative impact of aerosol for the reference wavelenght 550-nm) */ + WavelenghtSpectralType& WavelenghtSpectralBand, /** Wavelenght for the spectral band definition */ + /** Note : The Max wavelenght spectral band value must be updated ! */ + double & AtmosphericReflectance, /** Atmospheric reflectance */ + double & AtmosphericSphericalAlbedo, /** atmospheric spherical albedo */ + double & TotalGaseousTransmission, /** Total gaseous transmission */ + double & DownwardTransmittance, /** downward transmittance */ + double & UpwardTransmittance /** upward transmittance */ + ); + /** Generate WavelenghtSpectralBand if the step is not the official 6S step value */ + static void ComputeWavelenghtSpectralBandValuesFor6S( + const double SIXSStepOfWavelenghtSpectralBandValues, + WavelenghtSpectralType& WavelenghtSpectralBand + ); + +}; + +} // namespace otb + +#endif -- GitLab