29 : solver(Solver), atm(Atm), fm(Fm), meas(inst_meas)
41 : max_a_posteriori(Max_a_posteriori), atm(Atm), fm(Fm), meas(inst_meas)
57 fm(Fm), meas(inst_meas)
72 : max_a_posteriori(Max_a_posteriori),
74 fm(Fm), meas(inst_meas)
89 Array<double, 1> ErrorAnalysis::dxco2_dstate()
const 92 Array<double, 1> res(xco2().gradient().copy());
93 res = where(xco2_state_used(), res, 0.0);
109 return sum(dxco2_dstate()(i1) * averaging_kernel()(i1, i3) *
110 aposteriori_covariance()(i3, i2) * dxco2_dstate()(i2));
125 Array<bool, 1> xco2_state_usedv = xco2_state_used();
127 Array<double, 1> t(xco2_state_usedv.shape());
128 t = where(xco2_state_usedv, 1, 0);
129 Array<double, 2> ak(averaging_kernel());
130 Array<double, 2> ak_minus_i(ak.shape());
132 for(
int i = 0; i < ak_minus_i.rows(); ++i)
133 ak_minus_i(i, i) -= 1;
134 Array<double, 2>
s(apriori_covariance());
135 return sum(dxco2_dstate()(i1) * ak_minus_i(i1, i3) * t(i3) *
s(i3, i4) *
136 t(i4) * ak_minus_i(i2, i4) * dxco2_dstate()(i2));
151 Array<bool, 1> xco2_state_usedv = xco2_state_used();
153 Array<double, 1> t(xco2_state_usedv.shape());
154 t = where(xco2_state_usedv, 0, 1);
155 Array<double, 2> ak(averaging_kernel());
156 Array<double, 2>
s(apriori_covariance());
157 return sum(dxco2_dstate()(i1) * ak(i1, i3) * t(i3) *
s(i3, i4) * t(i4) *
158 ak(i2, i4) * dxco2_dstate()(i2));
189 Array<double, 1> result(meas->radiance_all().spectral_range().data().shape());
194 Logger::warning() <<
"Can not calculate xco2_gain_vector since solver is non ConnorSolver" <<
'\n';
205 Array<bool, 1> xco2_state_usedv = xco2_state_used();
206 Array<double, 1> sv_press_weighting(xco2_state_usedv.shape());
207 sv_press_weighting = 0;
211 Array<double, 1> press_wgt_grid(absorber->pressure_weighting_function_grid().value());
213 for(
int sv_idx = 0; sv_idx < xco2_state_usedv.rows() && p_wgt_idx < press_wgt_grid.rows(); sv_idx++) {
214 if(xco2_state_usedv(sv_idx)) {
215 sv_press_weighting(sv_idx) = press_wgt_grid(p_wgt_idx);
221 Array<double, 2> S(aposteriori_covariance());
224 Array<double, 1> Se(solver->residual_covariance_diagonal());
228 Array<double, 2> Sy_m1;
232 if(Se.rows() > 20000) {
233 Logger::error() <<
"Se is too big for calculating xco2_gain_vector. Se.rows() = " << Se.rows() <<
'\n';
237 Sy_m1.resize(Se.rows(), Se.rows());
238 }
catch (std::bad_alloc& ba) {
241 Logger::error() <<
"Se is too big for calculating xco2_gain_vector. Se.rows() = " << Se.rows() <<
'\n';
246 for(
int r_idx = 0; r_idx < Se.rows(); r_idx++) {
247 Sy_m1(r_idx, r_idx) = 1 / Se(r_idx);
251 Array<double, 2> Kt(solver->jacobian().transpose(secondDim, firstDim));
253 Array<double, 1> res1( sum(sv_press_weighting(i2) * S(i2, i1), i2) );
254 Array<double, 1> res2( sum(res1(i2) * Kt(i2, i1), i2) );
255 result = sum(res2(i2) * Sy_m1(i2, i1), i2);
258 Logger::warning() <<
"Can not calculate xco2_gain_vector since atmosphere->absorber() is not of type AbscoAbsorber" <<
'\n';
272 Array<double, 2> ErrorAnalysis::hmat()
const 275 int n = (solver ? solver->x_solution().rows() :
276 max_a_posteriori->parameters().rows());
277 Array<double, 2> res(n, n + 1);
279 res(Range::all(), 0) = dxco2_dstate();
280 for(
int i = 0; i < n; ++i)
293 Array<double, 2> ErrorAnalysis::ht_c_h()
const 296 Array<double, 2> h(hmat());
297 Array<double, 2> res(h.cols(), h.cols());
298 res = sum(sum(h(i3, i1) * aposteriori_covariance()(i3, i4) *
312 Array<double, 2> ht_c_h_v(ht_c_h());
313 Array<double, 1> res(ht_c_h_v.rows() - 1);
314 Range r(1, ht_c_h_v.rows() - 1);
315 double t = ht_c_h_v(0,0);
316 res = where(t * ht_c_h_v(r, r)(i1, i1) > 0,
317 ht_c_h_v(0, r) / sqrt(t * ht_c_h_v(r, r)(i1, i1)), 0);
331 Array<bool, 1> xco2_state_usedv = xco2_state_used();
332 Array<double, 1> res(count(xco2_state_usedv));
334 for(
int i = 0; i < xco2_state_usedv.rows(); ++i)
335 if(xco2_state_usedv(i))
336 res(ind++) = full_ak(i);
347 Array<double, 2> ak(averaging_kernel());
348 Array<double, 1> res(ak.cols());
349 res = sum(dxco2_dstate()(i2) * ak(i2, i1), i2);
362 Array<double, 2> ak(averaging_kernel());
363 Array<double, 1> full(ak.cols());
364 full = sum(dxco2_dstate()(i2) * ak(i2, i1), i2);
365 full = where(abs(dxco2_dstate()) > 1e-20, full / dxco2_dstate(), 0);
366 Array<bool, 1> xco2_state_usedv = xco2_state_used();
367 Array<double, 1> res(count(xco2_state_usedv));
369 for(
int i = 0; i < xco2_state_usedv.rows(); ++i)
370 if(xco2_state_usedv(i))
371 res(ind++) = full(i);
386 Array<double, 1> res(full_ak.shape());
387 Array<double, 2> cov(aposteriori_covariance());
389 res = (full_ak - dxco2_dstate()) *
390 where(cov(i1, i1) > 0, sqrt(cov(i1, i1)), 0);
406 if(
rad.data().rows() ==0)
408 Array<double, 1> r(
rad.data().copy());
409 std::sort(r.data(), r.data() + r.rows());
410 r.reverseSelf(firstDim);
411 Range r2(0, std::min(nrad - 1, r.rows() - 1));
412 return sum(r(r2) / r2.length());
422 DataRow(
int R,
double V) : row(R),
value(V) {}
427 class DataRowCompare {
429 bool operator()(
const DataRow& D1,
const DataRow& D2)
const 430 {
return D1.value > D2.value; }
447 if(
rad.data().rows() < nrad ||
rad.uncertainty().rows() < nrad)
449 std::vector<DataRow> dr;
450 dr.reserve(
rad.data().rows());
451 for(
int i = 0; i <
rad.data().rows(); ++i)
452 dr.push_back(DataRow(i,
rad.data()(i)));
453 std::sort(dr.begin(), dr.end(), DataRowCompare());
454 double sum_noise = 0;
455 for(
int i = 0; i < nrad; ++i)
456 sum_noise +=
rad.uncertainty()(dr[i].row);
458 return sum_noise / nrad;
468 firstIndex i1; secondIndex i2;
471 Array<double, 2> cov(aposteriori_covariance());
474 return sqrt(sum(dxco2_dstate()(i1) * cov * dxco2_dstate()(i2)));
485 Array<double, 2> ak(averaging_kernel());
486 Array<bool, 1> used(xco2_state_used());
487 int sz = count(used);
488 Array<double, 2> res(sz, sz);
490 for(
int i = 0; i < used.rows(); ++i)
493 for(
int j = 0; j < used.rows(); ++j)
495 res(ind1, ind2) = ak(i, j);
blitz::Array< double, 2 > co2_averaging_kernel() const
Portion of averaging kernel that relates the part of the state vector that is used by the CO2 VMR cal...
const Unit s("s", 1.0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
This class maintains the absorber portion of the state.
blitz::Array< double, 1 > xco2_gain_vector() const
This calculates xco2_gain_vector.
double signal(int band) const
Calculate an approximation to the size of the continuum signal where there is no significant atmosphe...
To detect things like divide by zero, we may turn on floating point exceptions.
double xco2_interference_error() const
Calculate XCO2 interference error.
#define REGISTER_LUA_CLASS(X)
Apply value function to a blitz array.
blitz::Array< double, 1 > xco2_avg_kernel_norm() const
Calculate the normalized XCO2 averaging kernel.
double xco2_uncertainty() const
XCO2 uncertainty.
blitz::Array< double, 1 > xco2_avg_kernel_full() const
This the XCO2 averaging kernel for the full state vector.
blitz::Array< double, 1 > xco2_avg_kernel() const
Calculate the XCO2 averaging kernel.
We have a number of different spectrums that appear in different parts of the code.
blitz::Array< double, 1 > interference_smoothing_uncertainty() const
Calculate the interference smoothing uncertainty.
double xco2_smoothing_error() const
Calculate XCO2 smoothing error.
double xco2_measurement_error() const
Calculate XCO2 measurement error.
blitz::Array< double, 1 > xco2_correlation_interf() const
Calculate xco2_correlation_interf.
Contains classes to abstract away details in various Spurr Radiative Transfer software.
#define REGISTER_LUA_END()
This calculates a variety of values to help with the error analysis of a Level 2 Full Physics Run...
This class maintains the atmosphere portion of the state, and uses this to set up the atmosphere and ...
ErrorAnalysis(const boost::shared_ptr< ConnorSolver > &Solver, const boost::shared_ptr< AtmosphereOco > &Atm, const boost::shared_ptr< ForwardModel > &Fm, const boost::shared_ptr< Observation > &inst_meas)
Constructor.
static LogHelper warning()
const Unit rad("rad", 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
double value(const FullPhysics::AutoDerivative< double > &Ad)
double noise(int band) const
Helper class for sort done in noise.