82 const Index& antenna_dim,
98 const Index n_ant = antenna_los.nrows();
101 assert( antenna_dim == 1 );
102 assert( antenna_los.ncols() == antenna_dim );
104 assert( n_pol >= 1 );
105 assert( do_norm >= 0 && do_norm <= 1 );
108 const Index n_ar_pol =
118 const Index n_ar_f = aresponse_f_grid.
nelem();
119 const Index n_ar_za = aresponse_za_grid.
nelem();
120 const Index pol_step = n_ar_pol > 1;
123 assert( n_ar_pol == 1 || n_ar_pol == n_pol );
125 assert( n_ar_za > 1 );
126 assert( n_ar_aa == 1 );
132 const Index nfpol = n_f * n_pol;
135 H.
resize( n_ant*nfpol, n_za*nfpol );
142 Vector aresponse( n_ar_za, 0.0 );
146 for(
Index ia=0; ia<n_ant; ia++ )
148 Vector shifted_aresponse_za_grid = aresponse_za_grid;
149 shifted_aresponse_za_grid += antenna_los(ia,0);
155 for(
Index f=0; f<n_f; f++ )
159 for(
Index ip=0; ip<n_pol; ip++ )
166 Index new_antenna = 1;
173 gridpos( gp_za, aresponse_za_grid, aresponse_za_grid );
176 Matrix aresponse_matrix(1,n_ar_za);
177 interp( aresponse_matrix, itw,
179 aresponse = aresponse_matrix(0,
joker);
183 aresponse = antenna_response.
data(ip,0,
joker,0);
187 aresponse = antenna_response.
data(0,0,
joker,0);
198 shifted_aresponse_za_grid,
202 { hza /= hza.
sum(); }
207 const Index ii = f*n_pol + ip;
209 hrow[
Range(ii,n_za,nfpol) ] = hza;
250 const Index& antenna_dim,
260 const Index do_norm )
264 const Index nfpol = n_f * n_pol;
267 const Index n_ant = antenna_los.nrows();
273 assert( antenna_dim == 2 );
275 assert( do_norm >= 0 && do_norm <= 1 );
284 aresponse.
resize( n_ar_pol, n_ar_f, n_ar_za, 1 );
288 H.
resize( n_ant*nfpol, n_aa*n_za*nfpol );
291 for(
Index il=0; il<n_ant; il++ )
296 for(
Index row=0; row<nfpol; row++ )
298 hrows[row].resize(n_aa*n_za*nfpol);
303 for(
Index ia=0; ia<n_aa; ia++ )
305 const Numeric aa_point = aa_grid[ia] - antenna_los(il,1);
307 if( aa_point >= response_aa_grid[0] &&
308 aa_point <=
last(response_aa_grid) )
316 for(
Index i4=0; i4<n_ar_pol; i4++ )
318 for(
Index i3=0; i3<n_ar_f; i3++ )
320 for(
Index i2=0; i2<n_ar_za; i2++ )
322 aresponse.
data(i4,i3,i2,0) =
323 gp[0].fd[1] * antenna_response.
data(i4,i3,i2,gp[0].idx) +
324 gp[0].fd[0] * antenna_response.
data(i4,i3,i2,gp[0].idx+1);
332 Numeric aa_low = response_aa_grid[0];
335 const Numeric aam = antenna_los(il,1) +
336 ( aa_grid[ia] + aa_grid[ia-1] ) / 2.0;
343 const Numeric aam = antenna_los(il,1) +
344 ( aa_grid[ia+1] + aa_grid[ia] ) / 2.0;
349 const Numeric aa_width = aa_high - aa_low;
356 aresponse, za_grid, f_grid, n_pol, 0 );
358 for(
Index row=0; row<nfpol; row++ )
360 for(
Index iz=0; iz<n_za; iz++ )
362 for(
Index i=0; i<nfpol; i++ )
364 hrows[row][(iz*n_aa+ia)*nfpol+i] =
365 aa_width * Hza(row,iz*nfpol+i);
373 for(
Index row=0; row<nfpol; row++ )
377 hrows[row] /= hrows[row].sum();
420 assert( dx_si <= xwidth_si );
425 const Index n = (
Index) floor(2*xwidth_si/dx_si) + 1;
428 const Numeric dd = si * xwidth_si;
459 const Numeric a = 1 / ( si * sqrt( 2 *
PI ) );
464 for(
Index i=0; i<n; i++ )
465 y[i] = a * exp( -0.5 * pow((x[i]-x0)/si,2.0) );
504 const Index& do_norm )
512 assert( lo > f_grid[0] );
513 assert( lo <
last(f_grid) );
514 assert( filter_grid.
nelem() == nrp );
515 assert( fabs(
last(filter_grid)+filter_grid[0]) < 1e3 );
543 const Numeric lim_high = -filter_grid[0];
547 list<Numeric> l_mixer;
550 if( fabs(f_grid[i]-lo)>=lim_low && fabs(f_grid[i]-lo)<=lim_high )
552 l_mixer.push_back(fabs(f_grid[i]-lo));
555 l_mixer.push_back(lim_high);
560 for (list<Numeric>::iterator li=l_mixer.begin(); li != l_mixer.end(); li++)
581 if_grid, f_mixer[i], -f_mixer[i] );
585 row_temp /= row_temp.
sum();
588 for (
Index p=0; p<n_pol; p++)
591 for (
Index a=0; a<n_sp; a++)
628 Vector& sensor_response_f,
630 Vector& sensor_response_za,
631 Vector& sensor_response_aa,
636 const Index za_aa_independent )
639 const Index nf = sensor_response_f_grid.
nelem();
640 const Index npol = sensor_response_pol_grid.
nelem();
641 const Index nza = sensor_response_za_grid.
nelem();
650 if( !za_aa_independent )
653 const Index n = nf * npol * nza * naa;
656 sensor_response_f.
resize( n );
657 sensor_response_pol.resize( n );
658 sensor_response_za.
resize( n );
660 { sensor_response_aa.
resize( 0 ); }
662 { sensor_response_aa.
resize( n ); }
665 for(
Index iaa=0; iaa<naa; iaa++ )
667 const Index i1 = iaa * nza * nf * npol;
669 for(
Index iza=0; iza<nza; iza++ )
671 const Index i2 = i1 + iza * nf * npol;
673 for(
Index ifr=0; ifr<nf; ifr++ )
675 const Index i3 = i2 + ifr * npol;
677 for(
Index ip=0; ip<npol; ip++ )
679 const Index i = i3 + ip;
681 sensor_response_f[i] = sensor_response_f_grid[ifr];
682 sensor_response_pol[i] = sensor_response_pol_grid[ip];
683 sensor_response_za[i] = sensor_response_za_grid[iza];
686 if( za_aa_independent )
687 sensor_response_aa[i] = sensor_response_aa_grid[iaa];
689 sensor_response_aa[i] = sensor_response_aa_grid[iza];
734 assert( h.
nelem() == ng );
735 assert( f.
nelem() == nf );
746 Index xg_reversed = 0;
750 x_g = x_g_in[
Range(ng-1,ng,-1)];
758 assert( x_g[0] <= xfmin );
759 assert( x_g[ng-1] >= xfmax );
762 const Numeric df = xfmax - xfmin;
765 for(
Index i=0; i<nf; i++ )
766 { x_f[i] = ( x_f_in[i] - xfmin ) / df; }
767 for(
Index i=0; i<ng; i++ )
768 { x_g[i] = ( x_g[i] - xfmin ) / df; }
779 for(
Index it=0; it<nf; it++ )
780 { l_x.push_back(x_f[it]); }
781 for (
Index it=0; it<ng; it++)
783 if( x_g[it] > xfmin && x_g[it] < xfmax )
784 { l_x.push_back(x_g[it]); }
791 for( list<Numeric>::iterator li=l_x.begin(); li != l_x.end(); li++ )
808 while( x_g[i_g+1] <= x_ref[i] )
810 while( x_f[i_f+1] <= x_ref[i] )
815 if( x_ref[i] >= xfmin && x_ref[i] < xfmax )
818 dx = ( x_f[i_f+1] - x_f[i_f] ) * ( x_g[i_g+1] - x_g[i_g] );
821 a0 = ( f[i_f] - f[i_f+1] ) / 3.0;
822 b0 = (-f[i_f] * ( x_g[i_g+1] + x_f[i_f+1] ) +
823 f[i_f+1] * (x_g[i_g+1]+x_f[i_f]) ) / 2.0;
824 c0 = x_g[i_g+1] * ( f[i_f] * x_f[i_f+1] - f[i_f+1] * x_f[i_f] );
827 b1 = ( f[i_f] * ( x_g[i_g] + x_f[i_f+1] ) -
828 f[i_f+1] * ( x_g[i_g] + x_f[i_f]) ) / 2.0;
829 c1 = x_g[i_g] * ( -f[i_f] * x_f[i_f+1] + f[i_f+1] * x_f[i_f] );
831 x1 = x_ref[i+1]-x_ref[i];
836 x2 = x1 * ( 2*x_ref[i] + x1 );
837 x3 = x1 * ( 3*x_ref[i]*(x_ref[i]+x1) + x1*x1 );
841 h[i_g] += df * ( a0*x3 +
b0*x2 + c0*x1 ) /
dx;
842 h[i_g+1] += df * ( a1*x3 + b1*x2 + c1*x1 ) /
dx;
856 if(
min(f) >= 0 &&
min(h) < -1e-15 )
857 throw runtime_error(
"Significant negative response value obtained, "
858 "despite sensor reponse is strictly positive. This "
859 "indicates numerical problems. Is there any very "
860 "small spacing of the sensor response grid?"
861 "Please, send a report to Patrick if you see this!" );
897 assert( h.
nelem() == ng );
898 assert( f.
nelem() == nf );
905 const Numeric xfmax = x_f[nf-1];
909 Index xg_reversed = 0;
913 x_g = x_g_in[
Range(ng-1,ng,-1)];
921 assert( x_g[0] <= xfmin );
922 assert( x_g[ng-1] >= xfmax );
928 for(
Index it=0; it<nf; it++ )
929 l_x.push_back(x_f[it]);
930 for(
Index it=0; it<ng; it++ )
932 if( x_g[it] > xfmin && x_g[it] < xfmax )
933 { l_x.push_back(x_g[it]); }
940 for( list<Numeric>::iterator li=l_x.begin(); li != l_x.end(); li++ )
958 while( x_g[i_g+1] <= x_ref[i] )
960 while( x_f[i_f+1] <= x_ref[i] )
965 if( x_ref[i] >= xfmin && x_ref[i] < xfmax )
968 const Numeric dxk = 0.5 * ( x_ref[i+1] - x_ref[i] );
971 const Numeric dxi = x_g[i_g+1] - x_g[i_g];
977 const Numeric dx = x_f[i_f+1] - x_f[i_f];
978 const Numeric f0 = ( f[i_f] * (x_f[i_f+1]-x_ref[i]) +
979 f[i_f+1] * (x_ref[i]-x_f[i_f]) ) /
dx;
980 const Numeric f1 = ( f[i_f] * (x_f[i_f+1]-x_ref[i+1]) +
981 f[i_f+1] * (x_ref[i+1]-x_f[i_f]) ) /
dx;
986 h[i_g] += r * ( f0 * ( x_g[i_g+1] - x_ref[i] ) +
987 f1 * ( x_g[i_g+1] - x_ref[i+1] ) );
988 h[i_g+1] += r * ( f0 * ( x_ref[i] - x_g[i_g] ) +
989 f1 * ( x_ref[i+1] - x_g[i_g] ) );
1041 assert( x_g[0] <= x_f[0] );
1043 assert( x1 >= x_f[0] );
1044 assert( x2 >= x_f[0] );
1045 assert( x1 <=
last(x_f) );
1046 assert( x2 <=
last(x_f) );
1056 interp( f1, itw1, f, gp1f );
1065 interp( f2, itw2, f, gp2f );
1069 h[gp1g[0].idx] += f1 * gp1g[0].fd[1];
1070 h[gp1g[0].idx+1] += f1 * gp1g[0].fd[0];
1071 h[gp2g[0].idx] += f2 * gp2g[0].fd[1];
1072 h[gp2g[0].idx+1] += f2 * gp2g[0].fd[0];
1103 const Index& do_norm )
1108 assert( ch_response.
nelem()==1 || ch_response.
nelem()==ch_f.
nelem() );
1119 const Index nin = n_sp * nin_f * n_pol;
1120 const Index nout = n_sp * nout_f * n_pol;
1129 Vector weights_long( nin, 0.0 );
1131 for(
Index ifr=0; ifr<nout_f; ifr++ )
1133 const Index irp = ifr * freq_full;
1136 ch_response_f = ch_response[irp].get_numeric_grid(
GFIELD1_F_GRID);
1137 ch_response_f += ch_f[ifr];
1141 ch_response_f, sensor_f );
1145 weights /= weights.
sum();
1149 for(
Index sp=0; sp<n_sp; sp++ )
1151 for(
Index pol=0; pol<n_pol; pol++ )
1154 weights_long[
Range(sp*nin_f*n_pol+pol,nin_f,n_pol)] = weights;
1157 H.
insert_row( sp*nout_f*n_pol + ifr*n_pol + pol, weights_long );
1255 assert(fmax.
nelem()==nf);
1256 assert(i>=0 && i<nf);
1257 assert(j>=0 && j<nf);
1258 assert(fmin[i]<=fmin[j]);
1267 if (fmax[i] >= fmin[j])
1273 if (fmax[j] > fmax[i])
1279 Index n_behind = nf-1 - j;
1285 fmin[
Range(j,n_behind)] = dummy[
Range(j+1,n_behind)];
1291 fmax[
Range(j,n_behind)] = dummy[
Range(j+1,n_behind)];
1345 os <<
"There must be at least one channel.\n"
1346 <<
"(The vector *f_backend* must have at least one element.)";
1347 throw runtime_error(os.str());
1351 if (n_chan != backend_channel_response.
nelem())
1354 os <<
"Variables *f_backend_multi* and *backend_channel_response_multi*\n"
1355 <<
"must have same number of bands for each LO.";
1356 throw runtime_error(os.str());
1360 for (
Index i=0; i<n_chan; ++i)
1363 const Vector& backend_f_grid = backend_channel_response[i].get_numeric_grid(0);
1368 os <<
"The frequency grid for the backend channel response of\n"
1369 <<
"channel " << i <<
" is not strictly increasing.\n";
1370 os <<
"It is: " << backend_f_grid <<
"\n";
1371 throw runtime_error( os.str() );
1378 out2 <<
" Original channel characteristics:\n"
1379 <<
" min nominal max (all in Hz):\n";
1386 for(
Index idx=0;idx<n_chan;++idx)
1388 const Vector& backend_filter = backend_channel_response[idx].data;
1389 if(backend_filter.
nelem()>2)
1391 for(
Index idy =1;idy < backend_filter.
nelem();++idy)
1393 if((backend_filter[idy] >0)&& (backend_filter[idy-1]==0))
1407 throw std::runtime_error(
"No passbands found.\n"
1408 "*backend_channel_response* must be zero around the passbands.\n"
1409 "backend_channel_response.data = [0, >0, >0, 0]\n"
1410 "Borders between passbands are identified as [...0,0...]");
1417 for(
Index idx=0;idx<n_chan;++idx)
1451 const Vector& backend_f_grid = backend_channel_response[idx].get_numeric_grid(0);
1452 const Vector& backend_filter = backend_channel_response[idx].data;
1453 if(backend_filter.
nelem()>=4)
1455 for(
Index idy =1;idy < backend_filter.
nelem();++idy)
1459 fmin_pb[pbIdx] = f_backend[idx]+backend_f_grid[0];
1461 else if((backend_filter[idy] >0) && (backend_filter[idy-1]==0))
1463 fmin_pb[pbIdx]= f_backend[idx] + backend_f_grid[idy-1]-delta;
1465 if((backend_filter[idy] ==0) && (backend_filter[idy-1]>0))
1467 fmax_pb[pbIdx]= f_backend[idx] + backend_f_grid[idy]+delta;
1468 out2 <<
" " <<
"fmin_pb "<< fmin_pb[pbIdx]
1469 <<
" " <<
"f_backend" <<f_backend[idx]
1470 <<
" " <<
"fmax_pb "<<fmax_pb[pbIdx]
1471 <<
" " <<
"diff " << fmax_pb[pbIdx]-fmin_pb[pbIdx]
1476 fmax_pb[pbIdx-1] = f_backend[idx]+
last(backend_f_grid);
1480 fmin_pb[pbIdx]= f_backend[idx] + backend_f_grid[0]-delta ;
1481 fmax_pb[pbIdx]= f_backend[idx] + backend_f_grid[backend_f_grid.
nelem()-1]+delta;
1482 out2 <<
" " <<
"fmin_pb "<< fmin_pb[pbIdx]
1483 <<
" " <<
"f_backend" <<f_backend[pbIdx]
1484 <<
" " <<
"fmax_pb "<<fmax_pb[pbIdx]
1509 out2 <<
" resize numPb "<<numPB<<
"\n";
1510 for(
Index idx = 0;idx<numPB;++idx)
1512 fmin[idx] = fmin_pb[isorted[idx]];
1513 fmax[idx] = fmax_pb[isorted[idx]];
1524 bool continue_checking =
true;
1528 while (continue_checking && i<fmin.
nelem()-1)
1539 out2 <<
" New channel characteristics:\n"
1540 <<
" min max (all in Hz):\n";
1542 out2 <<
" " << fmin[i] <<
" " << fmax[i] <<
"\n";