00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00029
00030
00031
00032
00033 #include <cmath>
00034 #include <list>
00035 #include "arts.h"
00036 #include "logic.h"
00037 #include "matpackI.h"
00038 #include "matpackII.h"
00039 #include "messages.h"
00040 #include "sensor.h"
00041
00042 extern const Numeric PI;
00043 extern const Index GFIELD1_F_GRID;
00044 extern const Index GFIELD4_FIELD_NAMES;
00045 extern const Index GFIELD4_F_GRID;
00046 extern const Index GFIELD4_ZA_GRID;
00047 extern const Index GFIELD4_AA_GRID;
00048
00049
00050
00051
00052
00053
00054
00055 void antenna1d_matrix(
00056 Sparse& H,
00057 #ifndef NDEBUG
00058 const Index& antenna_dim,
00059 #else
00060 const Index& antenna_dim _U_,
00061 #endif
00062 ConstMatrixView antenna_los,
00063 const GField4& antenna_response,
00064 ConstVectorView za_grid,
00065 ConstVectorView f_grid,
00066 const Index n_pol,
00067 const Index do_norm )
00068 {
00069
00070 const Index n_za = za_grid.nelem();
00071 const Index n_f = f_grid.nelem();
00072
00073
00074 const Index n_ant = antenna_los.nrows();
00075
00076
00077 assert( antenna_dim == 1 );
00078 assert( antenna_los.ncols() == antenna_dim );
00079 assert( n_za >= 2 );
00080 assert( n_pol >= 1 );
00081 assert( do_norm >= 0 && do_norm <= 1 );
00082
00083
00084 const Index n_ar_pol =
00085 antenna_response.get_string_grid(GFIELD4_FIELD_NAMES).nelem();
00086 ConstVectorView aresponse_f_grid =
00087 antenna_response.get_numeric_grid(GFIELD4_F_GRID);
00088 ConstVectorView aresponse_za_grid =
00089 antenna_response.get_numeric_grid(GFIELD4_ZA_GRID);
00090 DEBUG_ONLY( const Index n_ar_aa =
00091 antenna_response.get_numeric_grid(GFIELD4_AA_GRID).nelem(); )
00092
00093
00094 const Index n_ar_f = aresponse_f_grid.nelem();
00095 const Index n_ar_za = aresponse_za_grid.nelem();
00096 const Index pol_step = n_ar_pol > 1;
00097
00098
00099 assert( n_ar_pol == 1 || n_ar_pol == n_pol );
00100 assert( n_ar_f );
00101 assert( n_ar_za > 1 );
00102 assert( n_ar_aa == 1 );
00103
00104
00105
00106
00107
00108
00109 const Index nfpol = n_f * n_pol;
00110
00111
00112 H.resize( n_ant*nfpol, n_za*nfpol );
00113
00114
00115 Vector hrow( H.ncols(), 0.0 );
00116 Vector hza( n_za, 0.0 );
00117
00118
00119 Vector aresponse( n_ar_za, 0.0 );
00120
00121
00122
00123 for( Index ia=0; ia<n_ant; ia++ )
00124 {
00125 Vector shifted_aresponse_za_grid = aresponse_za_grid;
00126 shifted_aresponse_za_grid += antenna_los(ia,0);
00127
00128
00129
00130
00131
00132
00133 for( Index f=0; f<n_f; f++ )
00134 {
00135
00136
00137 for( Index ip=0; ip<n_pol; ip++ )
00138 {
00139
00140
00141
00142
00143
00144 Index new_antenna = 1;
00145
00146 if( n_ar_f > 1 )
00147 {
00148
00149 ArrayOfGridPos gp_f( 1 ), gp_za(n_za);
00150 gridpos( gp_f, aresponse_f_grid, Vector(1,f_grid[f]) );
00151 gridpos( gp_za, aresponse_za_grid, aresponse_za_grid );
00152 Tensor3 itw( 1, n_za, 4 );
00153 interpweights( itw, gp_f, gp_za );
00154 Matrix aresponse_matrix(1,n_za);
00155 interp( aresponse_matrix, itw,
00156 antenna_response(ip,joker,joker,0), gp_f, gp_za );
00157 aresponse = aresponse_matrix(0,joker);
00158 }
00159 else if( pol_step )
00160 {
00161 aresponse = antenna_response(ip,0,joker,0);
00162 }
00163 else if( f == 0 )
00164 {
00165 aresponse = antenna_response(0,0,joker,0);
00166 }
00167 else
00168 {
00169 new_antenna = 0;
00170 }
00171
00172
00173 if( new_antenna )
00174 {
00175 sensor_integration_vector( hza, aresponse,
00176 shifted_aresponse_za_grid,
00177 za_grid );
00178
00179 if( do_norm )
00180 { hza /= hza.sum(); }
00181 }
00182
00183
00184
00185 const Index ii = f*n_pol + ip;
00186
00187 hrow[ Range(ii,n_za,nfpol) ] = hza;
00188
00189 H.insert_row( ia*nfpol+ii, hrow );
00190
00191 hrow = 0;
00192 }
00193 }
00194 }
00195 }
00196
00197
00198
00200
00225 void mixer_matrix(
00226 Sparse& H,
00227 Vector& f_mixer,
00228 const Numeric& lo,
00229 const GField1& filter,
00230 ConstVectorView f_grid,
00231 const Index& n_pol,
00232 const Index& n_sp,
00233 const Index& do_norm )
00234 {
00235
00236 ConstVectorView filter_grid = filter.get_numeric_grid(GFIELD1_F_GRID);
00237
00238 DEBUG_ONLY( const Index nrp = filter.nelem(); )
00239
00240
00241 assert( lo > f_grid[0] );
00242 assert( lo < last(f_grid) );
00243 assert( filter_grid.nelem() == nrp );
00244 assert( fabs(last(filter_grid)+filter_grid[0]) < 1e3 );
00245
00246
00247
00248
00249 Index i_low = 0, i_high = f_grid.nelem()-1, i_mean;
00250 while( i_high-i_low > 1 )
00251 {
00252 i_mean = (Index) (i_high+i_low)/2;
00253 if (f_grid[i_mean]<lo)
00254 {
00255 i_low = i_mean;
00256 }
00257 else
00258 {
00259 i_high = i_mean;
00260 }
00261 }
00262 if (f_grid[i_high]==lo)
00263 {
00264 i_high++;
00265 }
00266
00267
00268 const Numeric lim_low = max( lo-f_grid[i_low], f_grid[i_high]-lo );
00269 const Numeric lim_high = -filter_grid[0];
00270
00271
00272
00273 list<Numeric> l_mixer;
00274 for( Index i=0; i<f_grid.nelem(); i++ )
00275 {
00276 if( fabs(f_grid[i]-lo)>=lim_low && fabs(f_grid[i]-lo)<=lim_high )
00277 {
00278 l_mixer.push_back(fabs(f_grid[i]-lo));
00279 }
00280 }
00281 l_mixer.push_back(lim_high);
00282 l_mixer.sort();
00283 l_mixer.unique();
00284 f_mixer.resize((Index) l_mixer.size());
00285 Index e=0;
00286 for (list<Numeric>::iterator li=l_mixer.begin(); li != l_mixer.end(); li++)
00287 {
00288 f_mixer[e] = *li;
00289 e++;
00290 }
00291
00292
00293 H.resize( f_mixer.nelem()*n_pol*n_sp, f_grid.nelem()*n_pol*n_sp );
00294
00295
00296
00297
00298 Vector row_temp( f_grid.nelem() );
00299 Vector row_final( f_grid.nelem()*n_pol*n_sp );
00300
00301 Vector if_grid = f_grid;
00302 if_grid -= lo;
00303
00304 for( Index i=0; i<f_mixer.nelem(); i++ )
00305 {
00306 sensor_summation_vector( row_temp, filter, filter_grid,
00307 if_grid, f_mixer[i], -f_mixer[i] );
00308
00309
00310 if (do_norm)
00311 row_temp /= row_temp.sum();
00312
00313
00314 for (Index p=0; p<n_pol; p++)
00315 {
00316
00317 for (Index a=0; a<n_sp; a++)
00318 {
00319
00320 row_final = 0.0;
00321 row_final[Range(a*f_grid.nelem()*n_pol+p,f_grid.nelem(),n_pol)]
00322 = row_temp;
00323 H.insert_row(a*f_mixer.nelem()*n_pol+p+i*n_pol,row_final);
00324 }
00325 }
00326 }
00327 }
00328
00329
00330
00332
00350 void sensor_aux_vectors(
00351 Vector& sensor_response_f,
00352 ArrayOfIndex& sensor_response_pol,
00353 Vector& sensor_response_za,
00354 Vector& sensor_response_aa,
00355 ConstVectorView sensor_response_f_grid,
00356 const ArrayOfIndex& sensor_response_pol_grid,
00357 ConstVectorView sensor_response_za_grid,
00358 ConstVectorView sensor_response_aa_grid )
00359 {
00360
00361 const Index nf = sensor_response_f_grid.nelem();
00362 const Index npol = sensor_response_pol_grid.nelem();
00363 const Index nza = sensor_response_za_grid.nelem();
00364 Index naa = sensor_response_aa_grid.nelem();
00365 Index empty_aa = 0;
00366
00367 if( naa == 0 )
00368 {
00369 empty_aa = 1;
00370 naa = 1;
00371 }
00372
00373 const Index n = nf * npol * nza * naa;
00374
00375
00376 sensor_response_f.resize( n );
00377 sensor_response_pol.resize( n );
00378 sensor_response_za.resize( n );
00379 if( empty_aa )
00380 { sensor_response_aa.resize( 0 ); }
00381 else
00382 { sensor_response_aa.resize( n ); }
00383
00384
00385 for( Index iaa=0; iaa<naa; iaa++ )
00386 {
00387 const Index i1 = iaa * nza * nf * npol;
00388
00389 for( Index iza=0; iza<nza; iza++ )
00390 {
00391 const Index i2 = i1 + iza * nf * npol;
00392
00393 for( Index ifr=0; ifr<nf; ifr++ )
00394 {
00395 const Index i3 = i2 + ifr * npol;
00396
00397 for( Index ip=0; ip<npol; ip++ )
00398 {
00399 const Index i = i3 + ip;
00400
00401 sensor_response_f[i] = sensor_response_f_grid[ifr];
00402 sensor_response_pol[i] = sensor_response_pol_grid[ip];
00403 sensor_response_za[i] = sensor_response_za_grid[iza];
00404 if( !empty_aa )
00405 { sensor_response_aa[i] = sensor_response_aa_grid[iaa]; }
00406 }
00407 }
00408 }
00409 }
00410 }
00411
00412
00413
00415
00439 void sensor_integration_vector(
00440 VectorView h,
00441 ConstVectorView f,
00442 ConstVectorView x_f_in,
00443 ConstVectorView x_g_in )
00444 {
00445
00446 const Index nf = x_f_in.nelem();
00447 const Index ng = x_g_in.nelem();
00448
00449
00450 assert( h.nelem() == ng );
00451 assert( f.nelem() == nf );
00452 assert( is_increasing( x_f_in ) );
00453 assert( is_increasing( x_g_in ) || is_decreasing( x_g_in ) );
00454
00455
00456
00457
00458
00459
00460
00461 Vector x_g = x_g_in;
00462 Vector x_f = x_f_in;
00463 Index xg_reversed = 0;
00464
00465 if( is_decreasing( x_g ) )
00466 {
00467 xg_reversed = 1;
00468 Vector tmp = x_g[Range(ng-1,ng,-1)];
00469 x_g = tmp;
00470 }
00471
00472 assert( x_g[0] <= x_f[0] );
00473 assert( x_g[ng-1] >= x_f[nf-1] );
00474
00475 const Numeric xmin = x_g[0];
00476 const Numeric xmax = x_g[ng-1];
00477
00478 x_f -= xmin;
00479 x_g -= xmin;
00480 x_f /= xmax - xmin;
00481 x_g /= xmax - xmin;
00482
00483
00484
00485
00486 list<Numeric> l_x;
00487 for( Index it=0; it<nf; it++ )
00488 l_x.push_back(x_f[it]);
00489 for (Index it=0; it<ng; it++)
00490 {
00491 if( x_g[it]>x_f[0] && x_g[it]<x_f[x_f.nelem()-1] )
00492 l_x.push_back(x_g[it]);
00493 }
00494
00495 l_x.sort();
00496 l_x.unique();
00497
00498 Vector x_ref(l_x.size());
00499 Index e=0;
00500 for (list<Numeric>::iterator li=l_x.begin(); li != l_x.end(); li++) {
00501 x_ref[e] = *li;
00502 e++;
00503 }
00504
00505
00506
00507 h = 0.0;
00508 Index i_f = 0;
00509 Index i_g = 0;
00510
00511 Numeric dx,a0,b0,c0,a1,b1,c1,x3,x2,x1;
00512
00513 for( Index i=0; i<x_ref.nelem()-1; i++ ) {
00514
00515
00516 while( x_g[i_g+1] <= x_ref[i] ) {
00517 i_g++;
00518 }
00519 while( x_f[i_f+1] <= x_ref[i] ) {
00520 i_f++;
00521 }
00522
00523
00524
00525 if( x_ref[i] >= x_f[0] && x_ref[i] < x_f[x_f.nelem()-1] ) {
00526
00527 dx = (x_f[i_f+1] - x_f[i_f]) * (x_g[i_g+1] - x_g[i_g]);
00528
00529
00530 a0 = (f[i_f] - f[i_f+1]) / 3;
00531 b0 = (-f[i_f]*(x_g[i_g+1]+x_f[i_f+1])+f[i_f+1]*(x_g[i_g+1]+x_f[i_f]))
00532 /2;
00533 c0 = f[i_f]*x_f[i_f+1]*x_g[i_g+1]-f[i_f+1]*x_f[i_f]*x_g[i_g+1];
00534
00535 a1 = -a0;
00536 b1 = (f[i_f]*(x_g[i_g]+x_f[i_f+1])-f[i_f+1]*(x_g[i_g]+x_f[i_f]))/2;
00537 c1 = -f[i_f]*x_f[i_f+1]*x_g[i_g]+f[i_f+1]*x_f[i_f]*x_g[i_g];
00538
00539 x3 = pow(x_ref[i+1],3) - pow(x_ref[i],3);
00540 x2 = pow(x_ref[i+1],2) - pow(x_ref[i],2);
00541 x1 = x_ref[i+1]-x_ref[i];
00542
00543
00544 h[i_g] += (a0*x3+b0*x2+c0*x1) / dx;
00545 h[i_g+1] += (a1*x3+b1*x2+c1*x1) / dx;
00546
00547 }
00548 }
00549
00550
00551 if( xg_reversed )
00552 {
00553 Vector tmp = h[Range(ng-1,ng,-1)];
00554 h = tmp;
00555 }
00556 }
00557
00558
00559
00561
00587 void sensor_summation_vector(
00588 VectorView h,
00589 ConstVectorView f,
00590 ConstVectorView x_f,
00591 ConstVectorView x_g,
00592 const Numeric x1,
00593 const Numeric x2 )
00594 {
00595
00596 assert( h.nelem() == x_g.nelem() );
00597 assert( f.nelem() == x_f.nelem() );
00598 assert( x_g[0] <= x_f[0] );
00599 assert( last(x_g) >= last(x_f) );
00600 assert( x1 >= x_f[0] );
00601 assert( x2 >= x_f[0] );
00602 assert( x1 <= last(x_f) );
00603 assert( x2 <= last(x_f) );
00604
00605
00606
00607 ArrayOfGridPos gp1g(1), gp1f(1);
00608 gridpos( gp1g, x_g, x1 );
00609 gridpos( gp1f, x_f, x1 );
00610 Matrix itw1(1,2);
00611 interpweights( itw1, gp1f );
00612 Numeric f1;
00613 interp( f1, itw1, f, gp1f );
00614
00615
00616 ArrayOfGridPos gp2g(1), gp2f(1);
00617 gridpos( gp2g, x_g, x2 );
00618 gridpos( gp2f, x_f, x2 );
00619 Matrix itw2(1,2);
00620 interpweights( itw2, gp2f );
00621 Numeric f2;
00622 interp( f2, itw2, f, gp2f );
00623
00624
00625 h = 0.0;
00626 h[gp1g[0].idx] += f1 * gp1g[0].fd[1];
00627 h[gp1g[0].idx+1] += f1 * gp1g[0].fd[0];
00628 h[gp2g[0].idx] += f2 * gp2g[0].fd[1];
00629 h[gp2g[0].idx+1] += f2 * gp2g[0].fd[0];
00630 }
00631
00632
00633
00635
00653 void spectrometer_matrix(
00654 Sparse& H,
00655 ConstVectorView ch_f,
00656 const ArrayOfGField1& ch_response,
00657 ConstVectorView sensor_f,
00658 const Index& n_pol,
00659 const Index& n_sp,
00660 const Index& do_norm )
00661 {
00662
00663
00664
00665 assert( ch_response.nelem()==1 || ch_response.nelem()==ch_f.nelem() );
00666
00667 Index freq_full = ch_response.nelem() > 1;
00668
00669
00670
00671
00672
00673
00674 const Index nin_f = sensor_f.nelem();
00675 const Index nout_f = ch_f.nelem();
00676 const Index nin = n_sp * nin_f * n_pol;
00677 const Index nout = n_sp * nout_f * n_pol;
00678
00679 H.resize( nout, nin );
00680
00681
00682
00683
00684 Vector ch_response_f;
00685 Vector weights( nin_f );
00686 Vector weights_long( nin, 0.0 );
00687
00688 for( Index ifr=0; ifr<nout_f; ifr++ )
00689 {
00690 const Index irp = ifr * freq_full;
00691
00692
00693 ch_response_f = ch_response[irp].get_numeric_grid(GFIELD1_F_GRID);
00694 ch_response_f += ch_f[ifr];
00695
00696
00697 sensor_integration_vector( weights, ch_response[irp],
00698 ch_response_f, sensor_f );
00699
00700
00701 if( do_norm )
00702 weights /= weights.sum();
00703
00704
00705
00706 for( Index sp=0; sp<n_sp; sp++ )
00707 {
00708 for( Index pol=0; pol<n_pol; pol++ )
00709 {
00710
00711 weights_long[Range(sp*nin_f*n_pol+pol,nin_f,n_pol)] = weights;
00712
00713
00714 H.insert_row( sp*nout_f*n_pol + ifr*n_pol + pol, weights_long );
00715
00716
00717 weights_long = 0.0;
00718 }
00719 }
00720 }
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00737
00796
00797