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