OTB  9.0.0
Orfeo Toolbox
otbReduceSpectralResponse.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbReduceSpectralResponse_hxx
22 #define otbReduceSpectralResponse_hxx
23 
24 #include <algorithm>
25 #include "itkNumericTraits.h"
27 
28 namespace otb
29 {
30 
31 template <class TSpectralResponse, class TRSR>
33 {
34  m_ReduceResponse = InputSpectralResponseType::New();
35 }
36 
37 template <class TSpectralResponse, class TRSR>
39 {
40  return (m_InputSatRSR->Clear() & m_InputSpectralResponse->Clear());
41 }
42 
43 template <typename T>
44 inline T trapezoid_area(T x1, T x2, T y1, T y2)
45 {
46  /* We compute the area of the trapezoid
47  by computing the lower square and the
48  upper triangle.
49  /- |y2
50  /- |
51  /- |
52  /- |
53  y1 +----------+
54  | |
55  | |
56  | |
57  +----------+
58  x1 x2
59 
60  (x2-x1)*min(y1,y2) + (x2-x1)*abs(y2-y1)/2
61  */
62  return (x2 - x1) * std::min(y1, y2) + (x2 - x1) * fabs(y2 - y1) * 0.5;
63 }
64 
65 template <class TSpectralResponse, class TRSR>
67 operator()(const unsigned int numBand)
68 {
69  if (numBand >= m_InputSatRSR->GetNbBands())
70  {
71  itkExceptionMacro(<< "There is no band num " << numBand << " in the RSR vector!(Size of the current RSR vector is " << m_InputSatRSR->GetNbBands() << ")");
72  }
73  else
74  {
75  ValuePrecisionType res = itk::NumericTraits<ValuePrecisionType>::ZeroValue();
76  typename InputRSRType::SpectralResponseType* solarIrradiance = this->m_InputSatRSR->GetSolarIrradiance();
77 
78  if (m_ReflectanceMode)
79  {
80  if (solarIrradiance == nullptr)
81  {
82  itkExceptionMacro(<< "Error occurs getting solar irradiance. Solar irradiance is mandatory using the reflectance mode.");
83  }
84  }
85  typename VectorPairType::const_iterator it;
86  VectorPairType pairs = (m_InputSatRSR->GetRSR())[numBand]->GetResponse();
87  it = pairs.begin();
88  ValuePrecisionType totalArea(0);
89  // start with the second value for the numerical integration
90  ++it;
91  while (it != pairs.end())
92  {
93  ValuePrecisionType rsr1 = (*(it - 1)).second;
94  ValuePrecisionType rsr2 = (*it).second;
95  if (rsr1 > 0 || rsr2 > 0)
96  {
97  PrecisionType lambda1 = (*(it - 1)).first;
98  PrecisionType lambda2 = (*it).first;
99  // PrecisionType deltaLambda = lambda2-lambda1;
100  ValuePrecisionType spectrum1 = (*m_InputSpectralResponse)(lambda1);
101  ValuePrecisionType spectrum2 = (*m_InputSpectralResponse)(lambda2);
102  /*
103  In order to simplify the computation for the reflectance mode,
104  we introduce the solar irradiance in the general formula with
105  a value of 1.0 for the radiance case.
106 
107  In this way the formula is the same if we weight the RSR by
108  the solar irradiance before the integration.
109  */
110  ValuePrecisionType solarIrradiance1(1.0);
111  ValuePrecisionType solarIrradiance2(1.0);
112  if (m_ReflectanceMode)
113  {
114  solarIrradiance1 = (*solarIrradiance)(lambda1);
115  solarIrradiance2 = (*solarIrradiance)(lambda2);
116  }
117  rsr1 *= solarIrradiance1;
118  rsr2 *= solarIrradiance2;
119  res += trapezoid_area(lambda1, lambda2, rsr1 * spectrum1, rsr2 * spectrum2);
120  totalArea += trapezoid_area(lambda1, lambda2, rsr1, rsr2);
121  }
122  ++it;
123  }
124  return res / totalArea;
125  }
126 }
127 
128 template <class TSpectralResponse, class TRSR>
130 {
131  m_ReduceResponse->Clear();
132  // Compute the reduce response for each band of the sensor
133  for (unsigned int i = 0; i < m_InputSatRSR->GetNbBands(); ++i)
134  {
135  m_InputSpectralResponse->SetPosGuessMin((this->m_InputSatRSR->GetRSR())[i]->GetInterval().first);
136  m_InputSpectralResponse->SetUsePosGuess(true);
137  PairType pair;
138  // pair.first = center wavelength of the band
139  pair.first = ((this->m_InputSatRSR->GetRSR())[i]->GetInterval().first + (this->m_InputSatRSR->GetRSR())[i]->GetInterval().second);
140  pair.first = pair.first / 2.0;
141  pair.second = (*this)(i);
142  m_ReduceResponse->GetResponse().push_back(pair);
143  m_InputSpectralResponse->SetUsePosGuess(false);
144  }
145 }
146 
147 
148 template <class TSpectralResponse, class TRSR>
149 void ReduceSpectralResponse<TSpectralResponse, TRSR>::LoadInputsFromFiles(const std::string& spectralResponseFile, const std::string& RSRFile,
150  const unsigned int nbRSRBands, ValuePrecisionType coefNormSpectre,
151  ValuePrecisionType coefNormRSR)
152 {
153  // Instantiation
154  m_InputSpectralResponse = InputSpectralResponseType::New();
156  m_InputSpectralResponse->Load(spectralResponseFile, coefNormSpectre);
157 
158  m_InputSatRSR = InputRSRType::New();
160  m_InputSatRSR->SetNbBands(nbRSRBands);
161 
163  m_InputSatRSR->Load(RSRFile, coefNormRSR);
164 }
165 
166 
167 template <class TSpectralResponse, class TRSR>
168 void ReduceSpectralResponse<TSpectralResponse, TRSR>::PrintSelf(std::ostream& os, itk::Indent indent) const
169 {
170  Superclass::PrintSelf(os, indent);
171  os << std::endl;
172  os << "spectre " << m_InputSpectralResponse << std::endl;
173  os << "Sat RSR " << m_InputSatRSR << std::endl;
174  os << std::endl;
175 
176  if (m_ReflectanceMode)
177  {
178  os << "Solar irradiance " << std::endl;
179  this->m_InputSatRSR->GetSolarIrradiance()->PrintSelf(os, indent);
180  os << std::endl;
181  os << indent << "[Center Wavelength (micrometers), Reflectance (percent)]" << std::endl;
182  }
183  else
184  {
185  os << indent << "[Center Wavelength (micrometers), Radiance (percent)]" << std::endl;
186  }
187 
188  for (typename VectorPairType::const_iterator it = m_ReduceResponse->GetResponse().begin(); it != m_ReduceResponse->GetResponse().end(); ++it)
189  {
190  os << indent << "Band Nb : " << it - m_ReduceResponse->GetResponse().begin() << ": [" << (*it).first << "," << (*it).second << "]" << std::endl;
191  }
192 }
193 
194 
195 } // end namespace otb
196 
197 #endif
otb::ReduceSpectralResponse::VectorPairType
InputSpectralResponseType::VectorPairType VectorPairType
Definition: otbReduceSpectralResponse.h:85
otb::ReduceSpectralResponse::PrecisionType
InputRSRType::PrecisionType PrecisionType
Definition: otbReduceSpectralResponse.h:82
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::ReduceSpectralResponse::CalculateResponse
void CalculateResponse()
Definition: otbReduceSpectralResponse.hxx:129
otb::ReduceSpectralResponse::m_ReduceResponse
InputSpectralResponsePointerType m_ReduceResponse
Definition: otbReduceSpectralResponse.h:158
otb::ReduceSpectralResponse::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbReduceSpectralResponse.hxx:168
otbReduceSpectralResponse.h
otb::ReduceSpectralResponse::LoadInputsFromFiles
void LoadInputsFromFiles(const std::string &spectralResponseFile, const std::string &RSRFile, const unsigned int nbRSRBands, ValuePrecisionType coefNormSpectre=1.0, ValuePrecisionType coefNormRSR=1.0)
Definition: otbReduceSpectralResponse.hxx:149
otb::ReduceSpectralResponse::ValuePrecisionType
InputRSRType::ValuePrecisionType ValuePrecisionType
Definition: otbReduceSpectralResponse.h:83
otb::ReduceSpectralResponse::operator()
ValuePrecisionType operator()(const unsigned int numBand)
Definition: otbReduceSpectralResponse.hxx:67
otb::ReduceSpectralResponse::PairType
InputSpectralResponseType::PairType PairType
Definition: otbReduceSpectralResponse.h:78
otb::trapezoid_area
T trapezoid_area(T x1, T x2, T y1, T y2)
Definition: otbReduceSpectralResponse.hxx:44
otb::ReduceSpectralResponse::ReduceSpectralResponse
ReduceSpectralResponse()
Definition: otbReduceSpectralResponse.hxx:32
otb::ReduceSpectralResponse::Clear
virtual bool Clear()
Definition: otbReduceSpectralResponse.hxx:38