19 #include "itkNumericTraits.h"
22 #include <boost/math/special_functions/expint.hpp>
23 #include <boost/shared_ptr.hpp>
27 #define EPSILON 0.0000000000000000000000001
36 this->ProcessObject::SetNumberOfRequiredInputs(1);
37 this->ProcessObject::SetNumberOfRequiredOutputs(2);
64 if(this->GetNumberOfInputs() != 1)
77 return static_cast<itk::DataObject *
>(SpectralResponseType::New().GetPointer());
85 if(this->GetNumberOfOutputs() < 2)
98 if(this->GetNumberOfOutputs() < 2)
113 if(params.
Size()!=6) itkExceptionMacro( <<
"Must have 6 parameters in that order : Cab, Car, CBrown, Cw, Cm, N" );
115 leafParams->SetCab(params[0]);
116 leafParams->SetCar(params[1]);
117 leafParams->SetCBrown(params[2]);
118 leafParams->SetCw(params[3]);
119 leafParams->SetCm(params[4]);
120 leafParams->SetN(params[5]);
136 unsigned int alpha=40;
137 double lambda, n, k, trans, t12, temp, t21, r12, r21, x, y, ra, ta, r90, t90;
138 double delta, beta, va, vb, vbNN, vbNNinv, vainv, s1, s2, s3, RN, TN;
139 double N, Cab, Car, CBrown, Cw, Cm;
141 N = leafParameters->GetN();
142 Cab = leafParameters->GetCab();
143 Car = leafParameters->GetCar();
144 CBrown = leafParameters->GetCBrown();
145 Cw = leafParameters->GetCw();
146 Cm = leafParameters->GetCm();
149 for (
int i = 0; i < nbdata; ++i)
157 if(k == itk::NumericTraits<double>::ZeroValue() ) k=
EPSILON;
159 trans=(1.-k)*exp(-k)+k*k*boost::math::expint(1, k);
161 t12 = this->Tav(alpha, n);
162 temp = this->Tav(90, n);
169 y = x*(temp-1)+1-t12;
171 ra = r12+(t12*t21*r21*(trans*trans))/(1.-r21*r21*trans*trans);
172 ta = (t12*t21*trans)/(1.-r21*r21*trans*trans);
176 delta = (t90*t90-r90*r90-1.)*(t90*t90-r90*r90-1.) - 4.*r90*r90;
178 else delta=vcl_sqrt(delta);
180 beta = (1.+r90*r90-t90*t90-delta)/(2.*r90);
181 va=(1.+r90*r90-t90*t90+delta)/(2.*r90);
183 vb=vcl_sqrt(beta*(va-r90)/(va*
EPSILON));
185 vb=vcl_sqrt(beta*(va-r90)/(va*(beta-r90)));
187 vbNN = vcl_pow(vb, N-1.);
190 s1=ta*t90*(vbNN-vbNNinv);
192 s3=va*vbNN-vainv*vbNNinv-r90*(vbNN-vbNNinv);
200 refl.first=lambda/1000.0;
202 trans.first=lambda/1000.0;
204 outRefl->GetResponse().push_back(refl);
205 outTrans->GetResponse().push_back(trans);
215 double theta_rad = theta*
CONST_PI/180;
216 double r2, rp, rm, a, k, ds, k2, rm2, res, b1, b2, b;
217 double ts, tp1, tp2, tp3, tp4, tp5, tp;
229 if(theta_rad==0) res=4*ref/((ref+1)*(ref+1));
232 if(theta_rad==
CONST_PI/2) b1=itk::NumericTraits<double>::ZeroValue();
233 else b1=vcl_sqrt((ds*ds-rp/2)*(ds*ds-rp/2)+k);
237 ts=(k2/(6*vcl_pow(b, 3))+k/b-b/2)-(k2/(6*vcl_pow(a, 3))+k/a-a/2);
238 tp1=-2*r2*(b-a)/(rp*rp);
239 tp2=-2*r2*rp*log(b/a)/rm2;
240 tp3=r2*(1./b-1./a)/2;
241 tp4=16*r2*r2*(r2*r2+1)*log((2*rp*b-rm2)/(2*rp*a-rm2))/(vcl_pow(rp, 3)*rm2);
242 tp5=16*vcl_pow(r2, 3)*(1./(2*rp*b-rm2)-1./(2*rp*a-rm2))/vcl_pow(rp, 3);
243 tp=tp1+tp2+tp3+tp4+tp5;
244 res=(ts+tp)/(2*ds*ds);
255 Superclass::PrintSelf(os, indent);