29 const static double CON = 6.73951496e-03;
31 const static double RADIUS = 6378.137e0;
49 firstIndex i1; secondIndex i2; thirdIndex i3;
50 Range ra = Range::all();
53 Array<double, 1> aband_data = l1b->radiance(0).data();
56 double wn_s0 = aband_solar_line_location.
value + aband_ils_offset.
value;
59 double V_cen = 497.2 * sin((l1b->time(0).frac_day_of_year() - 4.1) / 365.25 * 2 *
OldConstant::pi);
62 double sza_r = l1b->solar_zenith(0).convert(
Unit(
"rad")).value;
63 double saz_r = l1b->solar_azimuth(0).convert(
Unit(
"rad")).value;
64 double lat_r = l1b->latitude(0).convert(
Unit(
"rad")).value;
65 double geo_lat = atan(tan(lat_r) / (1.0 + CON));
66 double Rloc = 1000.0 * RADIUS / sqrt(1.0 + CON * std::pow(sin(geo_lat), 2));
67 double V_rot = -EARTH_ROT_SPD * Rloc * sin(sza_r) * cos(saz_r - 0.5 *
OldConstant::pi) * cos(geo_lat);
69 double solar_doppler_velocity = V_cen + V_rot;
77 Array<double, 1> aband_wn(aband_data.rows());
78 Poly1d aband_poly(disp_initial(0, ra).reverse(firstDim));
79 for(
int pix = 0; pix < aband_wn.rows(); pix++)
80 aband_wn(pix) = aband_poly(pix+1);
87 Array<double, 1>::const_iterator srch_beg =
88 std::lower_bound(aband_wn.begin(), aband_wn.end(), aband_solar_line_location.
value - aband_search_width.
value);
89 Array<double, 1>::const_iterator srch_end =
90 std::upper_bound(aband_wn.begin(), aband_wn.end(), aband_solar_line_location.
value + aband_search_width.
value);
91 Range srch_range(srch_beg.position()(0), srch_end.position()(0));
92 Array<double, 1> srch_wn(aband_wn(srch_range));
93 Array<double, 1> srch_data(aband_data(srch_range));
95 if (srch_wn.rows() == 0)
96 throw Exception(
"Could not find any points in the aband dispersion which encompass the fitting search window");
98 Array<double, 1> x( srch_wn - wn_s );
100 double mxmeas = max(srch_data);
101 double m2 = max(mxmeas - srch_data);
102 Array<double, 1> y( (mxmeas - srch_data) / m2 );
104 double cont_mean = 0;
106 for(
int idx = 0; idx < y.rows(); idx++) {
108 cont_mean = cont_mean + y(idx);
112 cont_mean = cont_mean / cont_count;
115 int pos = maxIndex(y)(0);
121 Array<double, 2>
K(y.rows(), 2);
122 double sig2 = aband_solar_line_width.
value;
123 Array<double, 1> ygauss( exp(-
pow2(x + fg) / (2.0 * sig2)) );
126 K(ra, 1) = -ygauss / sig2 * (x + fg);
130 Array<double, 2> Kt(
K.transpose(secondDim, firstDim) );
133 Array<double, 2> KtK( sum(Kt(i1, i3) *
K(i3, i2), i3) );
135 Array<double, 1> yminusg(y - ygauss);
136 Array<double, 1> Kty(sum(Kt(i1, i2) * yminusg(i2), i2));
137 Array<double, 1> delta(sum(KtK_m1(i1, i2) * Kty(i2), i2));
139 Array<double, 1>
fit(delta.rows());
143 double aband_shift =
fit(1);
146 std::cerr <<
"#sig2 = " << std::endl
148 <<
"# x = " << std::endl
150 <<
"# y = " << std::endl
152 <<
"# fit = " <<std::endl
154 <<
"# offset_scaling = "<<std::endl
155 << offset_scaling.
value << std::endl
156 <<
"# aband_shift = " << std::endl
157 << aband_shift << std::endl;
168 Array<double, 2> disp_adj(disp_initial.copy());
171 shift_.resize(disp_adj.rows());
173 for(
int band_idx = 0; band_idx < disp_adj.rows(); band_idx++) {
174 shift_(band_idx) = offset_scaling.
value(band_idx) * aband_shift;
175 disp_adj(band_idx, 0) = disp_adj(band_idx, 0) + shift_(band_idx);
183 Os <<
"DispersionFit\n";
blitz::Array< double, 2 > fit(const blitz::Array< double, 2 > disp_initial, const DoubleWithUnit &aband_solar_line_location, const DoubleWithUnit &aband_solar_line_width, const DoubleWithUnit &aband_search_width, const DoubleWithUnit &aband_ils_offset, const ArrayWithUnit< double, 1 > &offset_scaling) const
Given a single frame of data, estimate the spectral shift in band 1P.
This is the base of the exception hierarchy for Full Physics code.
This is used to read a Level 1B file.
blitz::Array< T, D > value
#define REGISTER_LUA_CLASS(X)
Apply value function to a blitz array.
const Unit K("K", 1.0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0)
blitz::Array< double, 2 > generalized_inverse(const blitz::Array< double, 2 > &A, double Rcond=std::numeric_limits< double >::epsilon())
This returns the generalized inverse of the given matrix.
A one-dimensional polynomial class.
FullPhysics::AutoDerivative< double > pow2(const FullPhysics::AutoDerivative< double > &x)
We frequently have a double with units associated with it.
blitz::Array< double, 1 > shift() const
Return computed shift in each band.
Libraries such as boost::units allow unit handling where we know the units at compile time...
Contains classes to abstract away details in various Spurr Radiative Transfer software.
#define REGISTER_LUA_END()
void print(std::ostream &Os) const
DispersionFit(const boost::shared_ptr< Level1bSampleCoefficient > &Level1b)
Initialize class with data needed to perform fit.
const DoubleWithUnit speed_of_light(299792458, units::m/units::s)
Speed of light, in m/s.