77 const Index& n_za_grid,
87 antenna_los(0,0) = 0.0;
95 cumsum[0] = r.
data(0,0,0,0);
96 for(
Index i=1; i<nr; i++ )
97 { cumsum[i] = cumsum[i-1] + r.
data(0,0,i,0); }
101 nlinspace( csp, cumsum[0], cumsum[nr-1], n_za_grid );
104 mblock_za_grid.
resize(n_za_grid);
109 interp( mblock_za_grid, itw, r_za_grid, gp );
121 const Index& atmosphere_dim,
132 if( sensor_pos.
ncols() != atmosphere_dim )
133 throw runtime_error(
"The number of columns of sensor_pos must be "
134 "equal to the atmospheric dimensionality." );
135 if( atmosphere_dim <= 2 && sensor_los.
ncols() != 1 )
137 "For 1D and 2D, sensor_los shall have one column." );
138 if( atmosphere_dim == 3 && sensor_los.
ncols() != 2 )
139 throw runtime_error(
"For 3D, sensor_los shall have two columns." );
140 if( sensor_los.
nrows() != nmblock )
143 os <<
"The number of rows of sensor_pos and sensor_los must be "
144 <<
"identical, but sensor_pos has " << nmblock <<
" rows,\n"
145 <<
"while sensor_los has " << sensor_los.
nrows() <<
" rows.";
146 throw runtime_error( os.str() );
148 if( antenna_dim == 2 && atmosphere_dim < 3 )
151 "If *antenna_dim* is 2, *atmosphere_dim* must be 3." );
153 if( antenna_dim != antenna_los.
ncols() )
156 "The number of columns of *antenna_los* must be *antenna_dim*.\n" );
160 const Matrix pos_copy = sensor_pos;
161 const Matrix los_copy = sensor_los;
163 sensor_pos.
resize( nmblock*nant, pos_copy.
ncols() );
164 sensor_los.
resize( nmblock*nant, los_copy.
ncols() );
166 for(
Index ib=0; ib<nmblock; ib++ )
168 for(
Index ia=0; ia<nant; ia++ )
170 const Index i = ib*nant + ia;
175 sensor_los(i,0) += antenna_los(ia,0);
176 if( antenna_dim == 2 )
177 sensor_los(i,1) += antenna_los(ia,1);
182 AntennaOff( antenna_dim, mblock_za_grid, mblock_aa_grid, verbosity );
184 antenna_los.
resize( 1, 1 );
199 out2 <<
" Sets the antenna dimensionality to 1.\n";
202 out2 <<
" Sets *mblock_za_grid* to have length 1 with value 0.\n";
204 mblock_za_grid[0] = 0;
206 out2 <<
" Sets *mblock_aa_grid* to be an empty vector.\n";
221 out2 <<
" Sets the antenna dimensionality to 1.\n";
222 out3 <<
" antenna_dim = 1\n";
223 out3 <<
" mblock_aa_grid is set to be an empty vector\n";
234 const Index& atmosphere_dim,
240 if( atmosphere_dim != 3 )
241 throw runtime_error(
"Antenna dimensionality 2 is only allowed when the "
242 "atmospheric dimensionality is 3." );
243 out2 <<
" Sets the antenna dimensionality to 1.\n";
244 out3 <<
" antenna_dim = 2\n";
287 r[0].set_name(
"Backend channel response function" );
291 r[0].set_grid_name( 0,
"Frequency" );
292 x[1] = resolution / 2.0;
294 r[0].set_grid( 0, x );
296 r[0].data.resize( 2 );
297 r[0].data[0] = 1/ resolution;
298 r[0].data[1] = r[0].data[0];
315 r[0].set_name(
"Backend channel response function" );
317 r[0].set_grid_name( 0,
"Frequency" );
318 r[0].set_grid( 0, x );
321 r[0].data.resize( n );
322 for(
Index i=0; i<n; i++ )
355 os <<
"There must be at least one channel.\n"
356 <<
"(The vector *lo* must have at least one element.)";
357 throw runtime_error(os.str());
362 (backend_channel_response.
nelem() != lo.
nelem()) )
365 os <<
"Variables *lo_multi*, *f_backend_multi* and *backend_channel_response_multi*\n"
366 <<
"must have same number of elements (number of LOs).";
367 throw runtime_error(os.str());
372 if (f_backend[i].nelem() != backend_channel_response[i].nelem())
375 os <<
"Variables *f_backend_multi* and *backend_channel_response_multi*\n"
376 <<
"must have same number of bands for each LO.";
377 throw runtime_error(os.str());
386 Vector f_backend_flat(2*n_chan);
397 const GriddedField1& this_grid = backend_channel_response[i][s];
398 const Numeric this_f_backend = f_backend[i][s];
401 f_backend_flat[j] = this_f_backend;
402 backend_channel_response_flat[j] = this_grid;
406 Numeric offset = this_f_backend - lo[i];
407 Numeric f_image = lo[i] - offset;
408 f_backend_flat[j] = f_image;
409 backend_channel_response_flat[j] = this_grid;
415 Vector fmin(2*n_chan), fmax(2*n_chan);
427 backend_channel_response_flat,
434 for (
Index i=0; i<fmin.nelem(); ++i)
437 const Numeric bw = fmax[i] - fmin[i];
440 const Numeric npf = ceil(bw/spacing);
450 Vector grid(fmin[i], npi, gs);
452 out3 <<
" Band range " << i <<
": " << grid <<
"\n";
455 f_grid_array.reserve(f_grid_array.
nelem()+npi);
456 for (
Index s=0; s<npi; ++s)
457 f_grid_array.push_back(grid[s]);
461 f_grid = f_grid_array;
463 out2 <<
" Total number of frequencies in f_grid: " << f_grid.
nelem() <<
"\n";
483 os <<
"Expected positive spacing. Found spacing to be: "
485 throw runtime_error(os.str());
499 backend_channel_response,
512 const Numeric bw = fmax[i] - fmin[i];
515 const Numeric npf = ceil(bw/spacing);
525 Vector grid(fmin[i], npi, gs);
527 out3 <<
" Band range " << i <<
": " << grid <<
"\n";
530 f_grid_array.reserve(f_grid_array.
nelem()+npi);
531 for (
Index s=0; s<npi; ++s)
532 f_grid_array.push_back(grid[s]);
536 f_grid = f_grid_array;
538 out2 <<
" Total number of frequencies in f_grid: " << f_grid.
nelem() <<
"\n";
546 Vector& sensor_response_f,
548 Vector& sensor_response_za,
549 Vector& sensor_response_aa,
550 Vector& sensor_response_za_grid,
551 Vector& sensor_response_aa_grid,
553 const Vector& sensor_response_f_grid,
555 const Index& atmosphere_dim,
556 const Index& antenna_dim,
557 const Matrix& antenna_los,
559 const Index& sensor_norm,
570 const Index nf = sensor_response_f_grid.
nelem();
571 const Index npol = sensor_response_pol_grid.
nelem();
572 const Index nza = sensor_response_za_grid.
nelem();
574 const Index nin = nf * npol * nza * naa;
578 bool error_found =
false;
582 if( sensor_response_f.
nelem() != nin )
584 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
585 <<
"grid variables (sensor_response_f_grid etc.).\n";
588 if( sensor_response.
nrows() != nin )
590 os <<
"The sensor block response matrix *sensor_response* does not have\n"
591 <<
"right size compared to the sensor grid variables\n"
592 <<
"(sensor_response_f_grid etc.).\n";
598 if( antenna_dim == 2 && atmosphere_dim < 3 )
600 os <<
"If *antenna_dim* is 2, *atmosphere_dim* must be 3.\n";
603 if( antenna_dim == 1 && sensor_response_aa_grid.
nelem() )
605 os <<
"If *antenna_dim* is 1, *sensor_response_aa_grid* (and\n"
606 <<
"*mblock_aa_grid*) must be empty.";
612 if( antenna_dim != antenna_los.
ncols() )
614 os <<
"The number of columns of *antenna_los* must be *antenna_dim*.\n";
622 const Index lpolgrid =
625 if( lpolgrid != 1 && lpolgrid != npol )
627 os <<
"The number of polarisation in *antenna_response* must be 1 or be\n"
628 <<
"equal to the number of polarisations used (determined by\n"
629 <<
"*stokes_dim* or *sensor_pol*).\n";
644 f_dlow =
min(sensor_response_f_grid) - aresponse_f_grid[0];
645 f_dhigh =
last(aresponse_f_grid) -
max(sensor_response_f_grid);
647 if( aresponse_f_grid.
nelem() > 1 )
651 os <<
"The frequency grid of *antenna_response is too narrow. It must\n"
652 <<
"cover all considered frequencies (*f_grid*), if the length\n"
653 <<
"is > 1. The grid needs to be expanded with "<<-f_dlow<<
" Hz in\n"
654 <<
"the lower end.\n";
659 os <<
"The frequency grid of *antenna_response is too narrow. It must\n"
660 <<
"cover all considered frequencies (*f_grid*), if the length\n"
661 <<
"is > 1. The grid needs to be expanded with "<<-f_dhigh<<
" Hz in\n"
662 <<
"the upper end.\n";
675 if( aresponse_za_grid.
nelem() < 2 )
677 os <<
"The zenith angle grid of *antenna_response* must have >= 2 values.\n";
688 za_dlow =
min(antenna_los(
joker,0)) + aresponse_za_grid[0] -
689 min(sensor_response_za_grid);
690 za_dhigh =
max(sensor_response_za_grid) - (
max(antenna_los(
joker,0)) +
691 last(aresponse_za_grid) );
695 os <<
"The WSV *sensor_response_za_grid* is too narrow. It should be\n"
696 <<
"expanded with "<<-za_dlow<<
" deg in the lower end. This change\n"
697 <<
"should be probably applied to *mblock_za_grid*.\n";
702 os <<
"The WSV *sensor_response_za_grid* is too narrow. It should be\n"
703 <<
"expanded with "<<-za_dhigh<<
" deg in the higher end. This change\n"
704 <<
"should be probably applied to *mblock_za_grid*.\n";
714 if( antenna_dim == 1 )
716 if( aresponse_aa_grid.
nelem() != 1 )
718 os <<
"The azimuthal dimension of *antenna_response* must be 1 if\n"
719 <<
"*antenna_dim* equals 1.\n";
727 if( aresponse_za_grid.
nelem() < 2 )
729 os <<
"The zenith angle grid of *antenna_response* must have >= 2\n"
739 aa_dlow =
min(antenna_los(
joker,1)) + aresponse_aa_grid[0] -
740 min(sensor_response_aa_grid);
741 aa_dhigh =
max(sensor_response_aa_grid) - (
max(antenna_los(
joker,1)) +
742 last(aresponse_aa_grid) );
746 os <<
"The WSV *sensor_response_aa_grid* is too narrow. It should be\n"
747 <<
"expanded with "<<-aa_dlow<<
" deg in the lower end. This change\n"
748 <<
"should be probably applied to *mblock_aa_grid*.\n";
753 os <<
"The WSV *sensor_response_aa_grid* is too narrow. It should be\n"
754 <<
"expanded with "<<-aa_dhigh<<
" deg in the higher end. This change\n"
755 <<
"should be probably applied to *mblock_aa_grid*.\n";
764 throw runtime_error(os.str());
772 if( antenna_dim == 1 )
774 sensor_response_za_grid, sensor_response_f_grid,
778 sensor_response_za_grid, sensor_response_aa_grid,
779 sensor_response_f_grid, npol, sensor_norm );
784 Sparse htmp = sensor_response;
786 mult( sensor_response, hantenna, htmp );
789 out3 <<
" Size of *sensor_response*: " << sensor_response.
nrows()
790 <<
"x" << sensor_response.
ncols() <<
"\n";
793 sensor_response_za_grid = antenna_los(
joker,0);
796 if( antenna_dim == 2 )
797 sensor_response_aa_grid = antenna_los(
joker,1);
801 sensor_response_za, sensor_response_aa,
802 sensor_response_f_grid, sensor_response_pol_grid,
803 sensor_response_za_grid, sensor_response_aa_grid, 0 );
813 Vector& sensor_response_f,
815 Vector& sensor_response_za,
816 Vector& sensor_response_aa,
817 Vector& sensor_response_f_grid,
820 const Vector& sensor_response_za_grid,
821 const Vector& sensor_response_aa_grid,
824 const Index& sensor_norm,
830 const Index nf = sensor_response_f_grid.
nelem();
831 const Index npol = sensor_response_pol_grid.
nelem();
832 const Index nza = sensor_response_za_grid.
nelem();
833 const Index naa = sensor_response_aa_grid.
nelem();
834 const Index nin = nf * npol * nza;
839 bool error_found =
false;
842 if( sensor_response_f.
nelem() != nin )
844 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
845 <<
"grid variables (sensor_response_f_grid etc.).\n";
848 if( naa && naa != nza )
850 os <<
"Incorrect size of *sensor_response_aa_grid*.\n";
853 if( sensor_response.
nrows() != nin )
855 os <<
"The sensor block response matrix *sensor_response* does not have\n"
856 <<
"right size compared to the sensor grid variables\n"
857 <<
"(sensor_response_f_grid etc.).\n";
862 if(
min(f_backend) <
min(sensor_response_f_grid) )
864 os <<
"At least one value in *f_backend* (" <<
min(f_backend)
865 <<
") below range\ncovered by *sensor_response_f_grid* ("
866 <<
min(sensor_response_f_grid) <<
").\n";
869 if(
max(f_backend) >
max(sensor_response_f_grid) )
871 os <<
"At least one value in *f_backend* (" <<
max(f_backend)
872 <<
") above range\ncovered by *sensor_response_f_grid* ("
873 <<
max(sensor_response_f_grid) <<
").\n";
879 const Index nrp = backend_channel_response.
nelem();
881 if( nrp != 1 && nrp != f_backend.
nelem() )
883 os <<
"The WSV *backend_channel_response* must have 1 or n elements,\n"
884 <<
"where n is the length of *f_backend*.\n";
891 throw runtime_error(os.str());
896 for(
Index i=0; i<nrp; i++ )
901 if( bchr_f_grid.
nelem() != backend_channel_response[i].data.
nelem() )
903 os <<
"Mismatch in size of grid and data in element " << i
904 <<
"\nof *sideband_response*.\n";
910 os <<
"The frequency grid of element " << i
911 <<
" in *backend_channel_response*\nis not strictly increasing.\n";
918 Numeric f1 = f_backend[i] + bchr_f_grid[0] -
min(sensor_response_f_grid);
920 f_backend[i]) -
last(bchr_f_grid);
922 f_dlow =
min( f_dlow, f1 );
923 f_dhigh =
min( f_dhigh, f2 );
928 os <<
"The WSV *sensor_response_f_grid* is too narrow. It should be\n"
929 <<
"expanded with "<<-f_dlow<<
" Hz in the lower end. This change\n"
930 <<
"should be applied to either *f_grid* or the sensor part in\n"
931 <<
"front of *sensor_responseBackend*.\n";
936 os <<
"The WSV *sensor_response_f_grid* is too narrow. It should be\n"
937 <<
"expanded with "<<-f_dhigh<<
" Hz in the higher end. This change\n"
938 <<
"should be applied to either *f_grid* or the sensor part in\n"
939 <<
"front of *sensor_responseBackend*.\n";
946 throw runtime_error(os.str());
954 sensor_response_f_grid, npol, nza, sensor_norm );
959 Sparse htmp = sensor_response;
961 mult( sensor_response, hbackend, htmp );
964 out3 <<
" Size of *sensor_response*: " << sensor_response.
nrows()
965 <<
"x" << sensor_response.
ncols() <<
"\n";
968 sensor_response_f_grid = f_backend;
972 sensor_response_za, sensor_response_aa,
973 sensor_response_f_grid, sensor_response_pol_grid,
974 sensor_response_za_grid, sensor_response_aa_grid, 0 );
981 Vector& sensor_response_f,
983 Vector& sensor_response_za,
984 Vector& sensor_response_aa,
985 Vector& sensor_response_f_grid,
987 const Vector& sensor_response_za_grid,
988 const Vector& sensor_response_aa_grid,
991 const Index& sensor_norm,
998 Sparse H1=sensor_response, H2=sensor_response;
1001 Vector f_backend_shifted;
1002 Vector fdummy=sensor_response_f, fdummy_grid=sensor_response_f_grid;
1005 f_backend_shifted = f_backend;
1006 f_backend_shifted += df1;
1009 sensor_response_za, sensor_response_aa,
1010 fdummy_grid, sensor_response_pol_grid,
1011 sensor_response_za_grid, sensor_response_aa_grid,
1012 f_backend_shifted, backend_channel_response,
1013 sensor_norm, verbosity);
1015 f_backend_shifted = f_backend;
1016 f_backend_shifted += df2;
1019 sensor_response_za, sensor_response_aa,
1020 sensor_response_f_grid, sensor_response_pol_grid,
1021 sensor_response_za_grid, sensor_response_aa_grid,
1022 f_backend_shifted, backend_channel_response,
1023 sensor_norm, verbosity);
1026 sub( sensor_response, H2, H1 );
1029 sensor_response_f_grid = f_backend;
1033 sensor_response_za, sensor_response_aa,
1034 sensor_response_f_grid, sensor_response_pol_grid,
1035 sensor_response_za_grid, sensor_response_aa_grid, 0 );
1043 Vector& sensor_response_f,
1045 Vector& sensor_response_za,
1046 Vector& sensor_response_aa,
1047 Vector& sensor_response_za_grid,
1048 Vector& sensor_response_aa_grid,
1050 const Vector& sensor_response_f_grid,
1058 if( sensor_response_za_grid.
nelem() != 2 )
1059 throw runtime_error(
1060 "This method requires that the number of observation directions is 2." );
1062 if( sensor_response_pol_grid.
nelem() != 1 )
1063 throw runtime_error(
1064 "This method handles (so far) only single polarisation cases." );
1066 const Index n = sensor_response_f_grid.
nelem();
1069 Sparse Hbswitch( n, 2*n );
1072 for(
Index i=0; i<n; i++ )
1085 Sparse Htmp = sensor_response;
1087 mult( sensor_response, Hbswitch, Htmp );
1090 out3 <<
" Size of *sensor_response*: " << sensor_response.
nrows()
1091 <<
"x" << sensor_response.
ncols() <<
"\n";
1094 const Numeric za = sensor_response_za_grid[1];
1095 sensor_response_za_grid.
resize(1);
1096 sensor_response_za_grid[0] = za;
1099 if( sensor_response_aa_grid.
nelem() > 0 )
1101 const Numeric aa = sensor_response_aa_grid[1];
1102 sensor_response_aa_grid.
resize(1);
1103 sensor_response_aa_grid[0] = aa;
1108 sensor_response_za, sensor_response_aa,
1109 sensor_response_f_grid, sensor_response_pol_grid,
1110 sensor_response_za_grid, sensor_response_aa_grid, 0 );
1118 Vector& sensor_response_f,
1120 Vector& sensor_response_za,
1121 Vector& sensor_response_aa,
1122 Vector& sensor_response_f_grid,
1125 const Vector& sensor_response_za_grid,
1126 const Vector& sensor_response_aa_grid,
1131 if( sensor_response_za_grid.
nelem() != 1 )
1132 throw runtime_error(
1133 "This method requires that the number of observation directions is 1." );
1135 if( sensor_response_pol_grid.
nelem() != 1 )
1136 throw runtime_error(
1137 "This method handles (so far) only single polarisation cases." );
1139 const Index n = sensor_response_f_grid.
nelem();
1140 const Index n2 = n/2;
1142 if( sensor_response.
nrows() != n )
1143 throw runtime_error(
"Assumptions of method are not fulfilled, "
1144 "considering number of rows in *sensor_response* "
1145 "and length of *sensor_response_f_grid*." );
1148 throw runtime_error(
"There is an odd number of total frequencies, "
1149 "which is not consistent with the assumptions of "
1154 Sparse Hbswitch( n2, n );
1157 for(
Index i=0; i<n2; i++ )
1170 Sparse Htmp = sensor_response;
1172 mult( sensor_response, Hbswitch, Htmp );
1175 out3 <<
" Size of *sensor_response*: " << sensor_response.
nrows()
1176 <<
"x" << sensor_response.
ncols() <<
"\n";
1179 const Vector f = sensor_response_f_grid;
1180 sensor_response_f_grid.
resize(n2);
1181 sensor_response_f_grid = f[
Range(n2,n2)];
1185 sensor_response_za, sensor_response_aa,
1186 sensor_response_f_grid, sensor_response_pol_grid,
1187 sensor_response_za_grid, sensor_response_aa_grid, 0 );
1194 Vector& sensor_response_f,
1195 Vector& sensor_response_f_grid,
1198 const String& sideband_mode,
1204 if(
max(sensor_response_f_grid) > f_lim )
1205 throw runtime_error(
"The frequencies seem to already be given in RF." );
1209 if( sideband_mode ==
"lower" )
1211 sensor_response_f *= -1;
1212 sensor_response_f_grid *= -1;
1213 sensor_response_f += lo;
1214 sensor_response_f_grid += lo;
1218 else if( sideband_mode==
"upper" )
1220 sensor_response_f += lo;
1221 sensor_response_f_grid += lo;
1227 throw runtime_error(
1228 "Only allowed options for *sideband _mode* are \"lower\" and \"upper\"." );
1237 Vector& sensor_response_f,
1239 Vector& sensor_response_za,
1240 Vector& sensor_response_aa,
1241 const Index& imblock,
1252 const Index na = sensor_response_array.
nelem();
1254 if( sensor_response_f_array.
nelem() != na ||
1255 sensor_response_pol_array.
nelem() != na ||
1256 sensor_response_za_array.
nelem() != na ||
1257 sensor_response_aa_array.
nelem() != na )
1259 throw runtime_error(
"All arrays (sensor_response_X_array) must have "
1260 "the same length." );
1262 if( imblock >= sensor_response_index.
nelem() )
1264 throw runtime_error(
"The given *imblock* is too high with respect "
1265 "to the length of *sensor_response_index*." );
1269 const Index i = sensor_response_index[imblock];
1273 throw runtime_error(
"The index extracted from *sensor_response_index* "
1274 "is too high with respect to the length of "
1275 "*sensor_response_array*." );
1279 sensor_response = sensor_response_array[i];
1280 sensor_response_f = sensor_response_f_array[i];
1281 sensor_response_pol = sensor_response_pol_array[i];
1282 sensor_response_za = sensor_response_za_array[i];
1283 sensor_response_aa = sensor_response_aa_array[i];
1291 Vector& sensor_response_f,
1293 Vector& sensor_response_za,
1294 Vector& sensor_response_aa,
1295 Vector& sensor_response_f_grid,
1298 const Vector& sensor_response_za_grid,
1299 const Vector& sensor_response_aa_grid,
1300 const Index& polyorder,
1307 const Index nf = sensor_response_f_grid.
nelem();
1308 const Index npol = sensor_response_pol_grid.
nelem();
1309 const Index nza = sensor_response_za_grid.
nelem();
1311 const Index nin = nf * npol * nza * naa;
1315 bool error_found =
false;
1318 if( sensor_response_f.
nelem() != nin )
1320 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1321 <<
"grid variables (sensor_response_f_grid etc.).\n";
1324 if( sensor_response.
nrows() != nin )
1326 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1327 <<
"right size compared to the sensor grid variables\n"
1328 <<
"(sensor_response_f_grid etc.).\n";
1333 if( polyorder < 2 || polyorder > 7 )
1335 os <<
"Accepted range for *polyorder* is [3,7].\n";
1340 os <<
"The argument *nfill* must be > 1.\n";
1347 throw runtime_error(os.str());
1352 const Index n1 = nfill+1;
1353 const Index n2 = nfill+2;
1354 const Index nnew = (nf-1)*n1 + 1;
1358 for(
Index i=0; i<nf-1; i++ )
1361 nlinspace( fp, sensor_response_f_grid[i], sensor_response_f_grid[i+1], n2 );
1362 fnew[
Range(i*n1,n2)] = fp;
1368 Matrix itw( nnew, polyorder+1 );
1370 gridpos_poly( gp, sensor_response_f_grid, fnew, polyorder );
1375 Sparse hpoly( nnew * npol * nza * naa, nin );
1379 for(
Index iza=0; iza<nza; iza++ )
1381 for(
Index iaa=0; iaa<naa; iaa++ )
1383 for(
Index iv=0; iv<nnew; iv++ )
1385 for(
Index ip=0; ip<npol; ip++ )
1387 const Index col0 = (iza*naa+iaa)*nf*npol;
1390 const Numeric w = gp[iv].w[i];
1393 hrow[col0+gp[iv].idx[i]*npol+ip] = w;
1398 { hrow[col0+gp[iv].idx[i]*npol+ip] = 0; }
1408 Sparse htmp = sensor_response;
1410 mult( sensor_response, hpoly, htmp );
1413 out3 <<
" Size of *sensor_response*: " << sensor_response.
nrows()
1414 <<
"x" << sensor_response.
ncols() <<
"\n";
1417 sensor_response_f_grid = fnew;
1421 sensor_response_za, sensor_response_aa,
1422 sensor_response_f_grid, sensor_response_pol_grid,
1423 sensor_response_za_grid, sensor_response_aa_grid, 1 );
1431 Vector& sensor_response_f,
1433 Vector& sensor_response_za,
1434 Vector& sensor_response_aa,
1435 Vector& sensor_response_f_grid,
1437 Vector& sensor_response_za_grid,
1438 Vector& sensor_response_aa_grid,
1441 const Vector& mblock_za_grid,
1442 const Vector& mblock_aa_grid,
1443 const Index& antenna_dim,
1444 const Index& atmosphere_dim,
1445 const Index& stokes_dim,
1446 const Index& sensor_norm,
1464 if( mblock_za_grid.
nelem() == 0 )
1465 throw runtime_error(
"The measurement block zenith angle grid is empty." );
1467 throw runtime_error(
1468 "The WSV *mblock_za_grid* must be strictly increasing or decreasing." );
1471 if( antenna_dim == 1 )
1473 if( mblock_aa_grid.
nelem() != 0 )
1474 throw runtime_error(
1475 "For antenna_dim = 1, the azimuthal angle grid must be empty." );
1479 if( atmosphere_dim < 3 )
1480 throw runtime_error(
"2D antennas (antenna_dim=2) can only be "
1481 "used with 3D atmospheres." );
1482 if( mblock_aa_grid.
nelem() == 0 )
1485 os <<
"The measurement block azimuthal angle grid is empty despite"
1486 <<
"a 2D antenna pattern is flagged (*antenna_dim*).";
1487 throw runtime_error( os.str() );
1490 throw runtime_error(
1491 "The WSV *mblock_aa_grid* must be strictly increasing or decreasing." );
1496 sensor_response_f_grid = f_grid;
1497 sensor_response_za_grid = mblock_za_grid;
1498 sensor_response_aa_grid = mblock_aa_grid;
1500 sensor_response_pol_grid.resize(stokes_dim);
1502 for(
Index is=0; is<stokes_dim; is++ )
1504 sensor_response_pol_grid[is] = is + 1;
1510 sensor_response_za, sensor_response_aa,
1511 sensor_response_f_grid, sensor_response_pol_grid,
1512 sensor_response_za_grid, sensor_response_aa_grid, 1 );
1518 out2 <<
" Initialising *sensor_reponse* as a identity matrix.\n";
1519 out3 <<
" Size of *sensor_response*: " << n <<
"x" << n <<
"\n";
1521 sensor_response.
make_I( n, n );
1528 Vector& sensor_response_f,
1530 Vector& sensor_response_za,
1531 Vector& sensor_response_aa,
1532 Vector& sensor_response_f_grid,
1534 Vector& sensor_response_za_grid,
1535 Vector& sensor_response_aa_grid,
1539 const Index& atmosphere_dim,
1540 const Index& stokes_dim,
1546 AntennaOff( antenna_dim, mblock_za_grid, mblock_aa_grid, verbosity );
1549 Index sensor_norm = 1;
1552 sensor_response_pol, sensor_response_za, sensor_response_aa,
1553 sensor_response_f_grid, sensor_response_pol_grid,
1554 sensor_response_za_grid, sensor_response_aa_grid, f_grid,
1555 mblock_za_grid, mblock_aa_grid, antenna_dim, atmosphere_dim,
1556 stokes_dim, sensor_norm, verbosity );
1564 Vector& sensor_response_f,
1566 Vector& sensor_response_za,
1567 Vector& sensor_response_aa,
1568 Vector& sensor_response_f_grid,
1571 const Vector& sensor_response_za_grid,
1572 const Vector& sensor_response_aa_grid,
1575 const Index& sensor_norm,
1581 const Index nf = sensor_response_f_grid.
nelem();
1582 const Index npol = sensor_response_pol_grid.
nelem();
1583 const Index nza = sensor_response_za_grid.
nelem();
1584 const Index naa = sensor_response_aa_grid.
nelem();
1585 const Index nin = nf * npol * nza;
1594 bool error_found =
false;
1597 if( sensor_response_f.
nelem() != nin )
1599 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1600 <<
"grid variables (sensor_response_f_grid etc.).\n";
1603 if( naa && naa != nza )
1605 os <<
"Incorrect size of *sensor_response_aa_grid*.\n";
1608 if( sensor_response.
nrows() != nin )
1610 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1611 <<
"right size compared to the sensor grid variables\n"
1612 <<
"(sensor_response_f_grid etc.).\n";
1617 if( lo <= sensor_response_f_grid[0] || lo >=
last(sensor_response_f_grid) )
1619 os <<
"The given local oscillator frequency is outside the sensor\n"
1620 <<
"frequency grid. It must be within the *sensor_response_f_grid*.\n";
1625 if( sbresponse_f_grid.
nelem() != sideband_response.
data.
nelem() )
1627 os <<
"Mismatch in size of grid and data in *sideband_response*.\n";
1630 if( sbresponse_f_grid.
nelem() < 2 )
1632 os <<
"At least two data points must be specified in "
1633 <<
"*sideband_response*.\n";
1638 os <<
"The frequency grid of *sideband_response* must be strictly\n"
1642 if( fabs(
last(sbresponse_f_grid)+sbresponse_f_grid[0]) > 1e3 )
1644 os <<
"The end points of the *sideband_response* frequency grid must be\n"
1645 <<
"symmetrically placed around 0. That is, the grid shall cover a\n"
1646 <<
"a range that can be written as [-df,df]. \n";
1651 Numeric df_high = lo +
last(sbresponse_f_grid) -
last(sensor_response_f_grid);
1652 Numeric df_low = sensor_response_f_grid[0] - lo - sbresponse_f_grid[0];
1653 if( df_high > 0 && df_low > 0 )
1655 os <<
"The *sensor_response_f* grid must be extended by at least\n"
1656 << df_low <<
" Hz in the lower end and " << df_high <<
" Hz in the\n"
1657 <<
"upper end to cover frequency range set by *sideband_response*\n"
1658 <<
"and *lo*. Or can the frequency grid of *sideband_response* be\n"
1662 else if( df_high > 0 )
1664 os <<
"The *sensor_response_f* grid must be extended by at " << df_high
1665 <<
" Hz\nin the upper end to cover frequency range set by\n"
1666 <<
"*sideband_response* and *lo*. Or can the frequency grid of\n"
1667 <<
"*sideband_response* be decreased?";
1670 else if( df_low > 0 )
1672 os <<
"The *sensor_response_f* grid must be extended by at " << df_low
1673 <<
" Hz\nin the lower end to cover frequency range set by\n"
1674 <<
"*sideband_response* and *lo*. Or can the frequency grid of\n"
1675 <<
"*sideband_response* be decreased?";
1682 throw runtime_error(os.str());
1691 sensor_response_f_grid, npol, nza, sensor_norm );
1696 Sparse htmp = sensor_response;
1698 mult( sensor_response, hmixer, htmp );
1701 out3 <<
" Size of *sensor_response*: " << sensor_response.
nrows()
1702 <<
"x" << sensor_response.
ncols() <<
"\n";
1705 sensor_response_f_grid = f_mixer;
1709 sensor_response_za, sensor_response_aa,
1710 sensor_response_f_grid, sensor_response_pol_grid,
1711 sensor_response_za_grid, sensor_response_aa_grid, 0 );
1718 Vector& sensor_response_f,
1720 Vector& sensor_response_za,
1721 Vector& sensor_response_aa,
1722 Vector& sensor_response_f_grid,
1725 const Vector& sensor_response_za_grid,
1726 const Vector& sensor_response_aa_grid,
1732 const Index& sensor_norm,
1736 const Index nf = sensor_response_f_grid.
nelem();
1737 const Index npol = sensor_response_pol_grid.
nelem();
1738 const Index nza = sensor_response_za_grid.
nelem();
1739 const Index naa = sensor_response_aa_grid.
nelem();
1740 const Index nin = nf * npol * nza;
1746 bool error_found =
false;
1749 if( sensor_response_f.
nelem() != nin )
1751 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1752 <<
"grid variables (sensor_response_f_grid etc.).\n";
1755 if( naa && naa != nza )
1757 os <<
"Incorrect size of *sensor_response_aa_grid*.\n";
1760 if( sensor_response.
nrows() != nin )
1762 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1763 <<
"right size compared to the sensor grid variables\n"
1764 <<
"(sensor_response_f_grid etc.).\n";
1770 if( sideband_response_multi.
nelem() != nlo )
1772 os <<
"Inconsistency in length between *lo_mixer* and "
1773 <<
"*sideband_response_multi*.\n";
1776 if( sideband_mode_multi.
nelem() != nlo )
1778 os <<
"Inconsistency in length between *lo_mixer* and "
1779 <<
"*sideband_mode_multi*.\n";
1782 if( f_backend_multi.
nelem() != nlo )
1784 os <<
"Inconsistency in length between *lo_mixer* and "
1785 <<
"*f_backend_multi*.\n";
1788 if( backend_channel_response_multi.
nelem() != nlo )
1790 os <<
"Inconsistency in length between *lo_mixer* and "
1791 <<
"*backend_channel_response_multi*.\n";
1798 throw runtime_error(os.str());
1806 for(
Index ilo=0; ilo<nlo; ilo++ )
1810 Sparse sr1 = sensor_response;
1811 Vector srf1 = sensor_response_f;
1813 Vector srza1 = sensor_response_za;
1814 Vector sraa1 = sensor_response_aa;
1815 Vector srfgrid1 = sensor_response_f_grid;
1821 sensor_response_pol_grid,
1822 sensor_response_za_grid,
1823 sensor_response_aa_grid,
1825 sideband_response_multi[ilo],
1831 sideband_mode_multi[ilo],
1835 sensor_response_pol_grid,
1836 sensor_response_za_grid,
1837 sensor_response_aa_grid,
1838 f_backend_multi[ilo],
1839 backend_channel_response_multi[ilo],
1840 sensor_norm, verbosity);
1842 catch( runtime_error e )
1845 os2 <<
"Error when dealing with receiver/mixer chain (1-based index) "
1846 << ilo+1 <<
":\n" << e.what();
1847 throw runtime_error(os2.str());
1851 sr.push_back( sr1 );
1852 srfgrid.push_back( srfgrid1 );
1854 cumsumf[ilo+1] = cumsumf[ilo] + srfgrid1.
nelem();
1859 const Index nfnew = cumsumf[nlo];
1860 sensor_response_f_grid.
resize( nfnew );
1862 for(
Index ilo=0; ilo<nlo; ilo++ )
1864 for(
Index i=0; i<srfgrid[ilo].
nelem(); i++ )
1866 sensor_response_f_grid[cumsumf[ilo]+i] = srfgrid[ilo][i];
1872 const Index ncols = sr[0].ncols();
1873 const Index npolnew = sensor_response_pol_grid.
nelem();
1874 const Index nfpolnew = nfnew * npolnew;
1876 sensor_response.
resize( nza*nfpolnew, ncols );
1878 Vector dummy( ncols, 0.0 );
1880 for(
Index ilo=0; ilo<nlo; ilo++ )
1882 const Index nfpolthis = (cumsumf[ilo+1]-cumsumf[ilo]) * npolnew;
1884 assert( sr[ilo].nrows() == nza*nfpolthis );
1885 assert( sr[ilo].ncols() == ncols );
1887 for(
Index iz=0; iz<nza; iz++ )
1889 for(
Index i=0; i<nfpolthis; i++ )
1892 for(
Index ic=0; ic<ncols; ic++ )
1893 { dummy[ic] = sr[ilo](iz*nfpolthis+i,ic); }
1895 sensor_response.
insert_row( iz*nfpolnew+cumsumf[ilo]*npolnew+i,
1903 sensor_response_za, sensor_response_aa,
1904 sensor_response_f_grid, sensor_response_pol_grid,
1905 sensor_response_za_grid, sensor_response_aa_grid, 0 );
1913 Vector& sensor_response_f,
1915 Vector& sensor_response_za,
1916 Vector& sensor_response_aa,
1919 const Vector& sensor_response_f_grid,
1920 const Vector& sensor_response_za_grid,
1921 const Vector& sensor_response_aa_grid,
1922 const Index& stokes_dim,
1932 if( y_unit ==
"PlanckBT" || y_unit ==
"RJBT" )
1948 const Index nf = sensor_response_f_grid.
nelem();
1949 const Index npol = sensor_response_pol_grid.
nelem();
1950 const Index nza = sensor_response_za_grid.
nelem();
1954 bool error_found =
false;
1959 bool za_aa_independent =
true;
1962 Index nfz = nf * nza;
1963 Index nin = nfz *npol;
1965 if( sensor_response.
nrows() == nin )
1966 { za_aa_independent =
false; }
1967 else if( sensor_response.
nrows() == nin*naa )
1968 { nfz *= naa; nin *= naa; }
1971 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1972 <<
"right size compared to the sensor grid variables\n"
1973 <<
"(sensor_response_f_grid etc.).\n";
1978 if( sensor_response_f.
nelem() != nin )
1980 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1981 <<
"grid variables (sensor_response_f_grid etc.).\n";
1984 if( naa && naa != nza )
1986 os <<
"Incorrect size of *sensor_response_aa_grid*.\n";
1989 if( npol != stokes_dim )
1991 os <<
"Number of input polarisation does not match *stokes_dim*.\n";
1996 os <<
"The WSV *sensor_pol* can not be empty.\n";
2002 throw runtime_error(os.str());
2005 for(
Index i=0; i<npol && !error_found; i++ )
2007 if( sensor_response_pol_grid[i] != i+1 )
2009 os <<
"The input polarisations must be I, Q, U and V (up to "
2010 <<
"stokes_dim). It seems that input data are for other "
2011 <<
"polarisation components.";
2015 for(
Index i=0; i<nnew && !error_found; i++ )
2017 if( sensor_pol[i] < 1 || sensor_pol[i] > 10 )
2020 "The elements of *sensor_pol* must be inside the range [1,10].\n";
2027 throw runtime_error(os.str());
2029 for(
Index i=0; i<nnew && !error_found; i++ )
2031 if( pv[sensor_pol[i]-1].nelem() > stokes_dim )
2033 os <<
"You have selected an output polarisation that is not covered "
2034 <<
"by present value of *stokes_dim* (the later has to be "
2042 throw runtime_error(os.str());
2046 Sparse Hpol( nfz*nnew, nin );
2050 for(
Index i=0; i<nfz; i++ )
2053 for(
Index in=0; in<nnew; in++ )
2055 Index p = sensor_pol[in] - 1;
2058 { hrow[col+iv] = pv[p][iv]; }
2070 Sparse Htmp = sensor_response;
2072 mult( sensor_response, Hpol, Htmp );
2075 sensor_response_pol_grid = sensor_pol;
2079 sensor_response_za, sensor_response_aa,
2080 sensor_response_f_grid, sensor_response_pol_grid,
2081 sensor_response_za_grid, sensor_response_aa_grid,
2082 za_aa_independent );
2093 Vector& sensor_response_f,
2095 Vector& sensor_response_za,
2096 Vector& sensor_response_aa,
2097 Vector& sensor_response_f_grid,
2099 Vector& sensor_response_za_grid,
2100 Vector& sensor_response_aa_grid,
2103 const Index& atmosphere_dim,
2104 const Index& stokes_dim,
2105 const Matrix& sensor_description_amsu,
2111 if ( 3 != sensor_description_amsu.
ncols() )
2114 os <<
"Input variable sensor_description_amsu must have three columns, but it has "
2115 << sensor_description_amsu.
ncols() <<
".";
2116 throw runtime_error( os.str() );
2120 const Index n = sensor_description_amsu.
nrows();
2131 for (
Index i=0; i<n; ++i) {
2132 Vector& f = f_backend_multi[i];
2134 f[0] = lo_multi[i] + offset[i];
2139 for (
Index i=0; i<n; ++i) {
2140 backend_channel_response_multi[i].resize(1);
2142 r.
set_name(
"Backend channel response function");
2147 f[0] = - 0.5 * width[i];
2148 f[1] = + 0.5 * width[i];
2159 for (
Index i=0; i<n; ++i) {
2161 r.
set_name(
"Sideband response function");
2166 f[0] = - (offset[i] + 0.5*width[i]);
2167 f[1] = + (offset[i] + 0.5*width[i]);
2186 f_backend_multi, backend_channel_response_multi,
2187 spacing, verbosity);
2189 AntennaOff(antenna_dim, mblock_za_grid, mblock_aa_grid, verbosity);
2192 sensor_response_f, sensor_response_pol,
2193 sensor_response_za, sensor_response_aa,
2194 sensor_response_f_grid,
2195 sensor_response_pol_grid,
2196 sensor_response_za_grid,
2197 sensor_response_aa_grid, f_grid, mblock_za_grid,
2198 mblock_aa_grid, antenna_dim, atmosphere_dim,
2199 stokes_dim, sensor_norm,
2203 sensor_response_pol,
2206 sensor_response_f_grid,
2207 sensor_response_pol_grid,
2208 sensor_response_za_grid,
2209 sensor_response_aa_grid, lo_multi,
2210 sideband_response_multi,
2211 sideband_mode_multi,
2213 backend_channel_response_multi,
2262 if ( (wmrf_weights.
nrows() != f_backend.
nelem()) ||
2265 os <<
"The WSV *wmrf_weights* must have same number of rows as\n"
2266 <<
"*f_backend*, and same number of columns as *f_grid*.\n"
2267 <<
"wmrf_weights.nrows() = " << wmrf_weights.
nrows() <<
"\n"
2268 <<
"f_backend.nelem() = " << f_backend.
nelem() <<
"\n"
2269 <<
"wmrf_weights.ncols() = " << wmrf_weights.
ncols() <<
"\n"
2270 <<
"f_grid.nelem() = " << f_grid.
nelem();
2271 throw runtime_error(os.str());
2279 if (
min(wmrf_channels)<0 )
2281 os <<
"Min(wmrf_channels) must be >= 0, but it is "
2282 <<
min(wmrf_channels) <<
".";
2284 if (
max(wmrf_channels)>=f_backend.
nelem() )
2286 os <<
"Max(wmrf_channels) must be less than the total number of channels.\n"
2287 <<
"(We use zero-based indexing!)\n"
2288 <<
"The actual value you have is "
2289 <<
max(wmrf_channels) <<
".";
2292 if (wmrf_channels.
nelem()==f_backend.
nelem())
2295 out2 <<
" Retaining all channels.\n";
2299 out2 <<
" Reducing number of channels from "
2300 << f_backend.
nelem() <<
" to " << wmrf_channels.
nelem() <<
".\n";
2307 Select(f_backend, f_backend, wmrf_channels, verbosity);
2312 Select(wmrf_weights, wmrf_weights, wmrf_channels, verbosity);
2323 selection.reserve(f_grid.
nelem());
2327 assert( wmrf_weights.
nrows() == f_backend.
nelem() );
2328 assert( wmrf_weights.
ncols() == f_grid.
nelem() );
2329 for (
Index fi=0; fi<wmrf_weights.
ncols(); ++fi)
2332 for (i=0; i<wmrf_weights.
nrows(); ++i)
2334 if ( wmrf_weights(i,fi) != 0 )
2336 selection.push_back(fi);
2340 if (i==wmrf_weights.
nrows())
2342 out3 <<
" The frequency with index " << fi
2343 <<
" is not used by any channel.\n";
2350 out2 <<
" No unnecessary frequencies, leaving f_grid untouched.\n";
2352 else if (selection.
nelem() == 0)
2354 throw runtime_error(
"No frequencies found for any selected channels.\n");
2358 out2 <<
" Reducing number of frequency grid points from "
2359 << f_grid.
nelem() <<
" to " << selection.
nelem() <<
".\n";
2363 Select(f_grid, f_grid, selection, verbosity);
2370 Select(wt, wt, selection, verbosity);
2379 Vector& sensor_response_f,
2381 Vector& sensor_response_za,
2382 Vector& sensor_response_aa,
2383 Vector& sensor_response_f_grid,
2386 const Vector& sensor_response_za_grid,
2387 const Vector& sensor_response_aa_grid,
2388 const Sparse& wmrf_weights,
2395 const Index nf = sensor_response_f_grid.
nelem();
2396 const Index npol = sensor_response_pol_grid.
nelem();
2397 const Index nza = sensor_response_za_grid.
nelem();
2398 const Index naa = sensor_response_aa_grid.
nelem();
2399 const Index nin = nf * npol * nza;
2404 bool error_found =
false;
2407 if( sensor_response_f.
nelem() != nin )
2409 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
2410 <<
"grid variables (sensor_response_f_grid etc.).\n";
2413 if( naa && naa != nza )
2415 os <<
"Incorrect size of *sensor_response_aa_grid*.\n";
2418 if( sensor_response.
nrows() != nin )
2420 os <<
"The sensor block response matrix *sensor_response* does not have\n"
2421 <<
"right size compared to the sensor grid variables\n"
2422 <<
"(sensor_response_f_grid etc.).\n";
2428 os <<
"One of f_grid, pol_grid, za_grid are empty. Sizes are: ("
2429 << nf <<
", " << npol <<
", " << nza <<
")" <<
"\n";
2435 if(
min(f_backend) <
min(sensor_response_f_grid) )
2437 os <<
"At least one value in *f_backend* (" <<
min(f_backend)
2438 <<
") below range\ncovered by *sensor_response_f_grid* ("
2439 <<
min(sensor_response_f_grid) <<
").\n";
2442 if(
max(f_backend) >
max(sensor_response_f_grid) )
2444 os <<
"At least one value in *f_backend* (" <<
max(f_backend)
2445 <<
") above range\ncovered by *sensor_response_f_grid* ("
2446 <<
max(sensor_response_f_grid) <<
").\n";
2455 if( nrw != f_backend.
nelem() )
2457 os <<
"The WSV *wmrf_weights* must have as many rows\n"
2458 <<
"as *f_backend* has elements.\n"
2459 <<
"wmrf_weights.nrows() = " << nrw <<
"\n"
2460 <<
"f_backend.nelem() = " << f_backend.
nelem() <<
"\n";
2468 if( ncw != sensor_response_f_grid.
nelem() )
2470 os <<
"The WSV *wmrf_weights* must have as many columns\n"
2471 <<
"as *sensor_response_f_grid* has elements.\n"
2472 <<
"wmrf_weights.ncols() = " << ncw <<
"\n"
2473 <<
"sensor_response_f_grid.nelem() = " << sensor_response_f_grid.
nelem() <<
"\n";
2480 throw runtime_error(os.str());
2488 Sparse htmp = sensor_response;
2490 mult( sensor_response, wmrf_weights, htmp );
2493 out3 <<
" Size of *sensor_response*: " << sensor_response.
nrows()
2494 <<
"x" << sensor_response.
ncols() <<
"\n";
2497 sensor_response_f_grid = f_backend;
2501 sensor_response_za, sensor_response_aa,
2502 sensor_response_f_grid, sensor_response_pol_grid,
2503 sensor_response_za_grid, sensor_response_aa_grid, 0 );
2515 const Sparse& sensor_response,
2516 const Vector& sensor_response_f,
2518 const Vector& sensor_response_za,
2519 const Vector& sensor_response_aa,
2523 sensor_response_array.resize(1);
2524 sensor_response_f_array.resize(1);
2525 sensor_response_pol_array.resize(1);
2526 sensor_response_za_array.resize(1);
2527 sensor_response_aa_array.resize(1);
2530 sensor_response_array[0] = sensor_response;
2531 sensor_response_f_array[0] = sensor_response_f;
2532 sensor_response_pol_array[0] = sensor_response_pol;
2533 sensor_response_za_array[0] = sensor_response_za;
2534 sensor_response_aa_array[0] = sensor_response_aa;