Go to the documentation of this file.
76 const Index& n_za_grid,
81 if (dx_si > xwidth_si)
82 throw runtime_error(
"It is demanded that dx_si <= xwidth_si.");
98 for (
Index i = 1; i < nr; i++) {
99 cumtrapz[i] = cumtrapz[i - 1] + r.
data(0, 0, i - 1, 0) + r.
data(0, 0, i, 0);
104 nlinspace(csp, cumtrapz[0], cumtrapz[nr - 1], n_za_grid);
135 "The number of columns of sensor_pos must be "
136 "equal to the atmospheric dimensionality.");
138 throw runtime_error(
"For 1D and 2D, sensor_los shall have one column.");
140 throw runtime_error(
"For 3D, sensor_los shall have two columns.");
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());
149 throw runtime_error(
"If *antenna_dim* is 2, *atmosphere_dim* must be 3.");
151 if (
antenna_dlos.empty())
throw runtime_error(
"*antenna_dlos* is empty.");
153 throw runtime_error(
"*antenna_dlos* must have one or 2 columns.");
156 "*antenna_dlos* can only have two columns for 3D atmosphers.");
165 for (
Index ib = 0; ib < nmblock; ib++) {
166 for (
Index ia = 0; ia < nant; ia++) {
167 const Index i = ib * nant + ia;
192 out2 <<
" Sets the antenna dimensionality to 1.\n";
195 out2 <<
" Sets *mblock_dlos_grid* to have one row with value 0.\n";
209 if (dx_si > xwidth_si)
210 throw runtime_error(
"It is demanded that dx_si <= xwidth_si.");
228 const Index n =
y.nelem();
238 for (
Index z = 0; z < n; z++) {
239 for (
Index b = 0; b < n; b++) {
241 a * exp(-0.5 *
pow(
sqrt(
x[z] *
x[z] +
x[b] *
x[b]) / si, 2.0));
263 if (dx_si > xwidth_si)
264 throw runtime_error(
"It is demanded that dx_si <= xwidth_si.");
271 x,
y, 0, fwhm, (fstop / fstart) * xwidth_si, dx_si);
288 const Index n =
y.nelem();
294 for (
Index i = 0; i < nf; i++) {
299 for (
Index z = 0; z < n; z++) {
300 for (
Index b = 0; b < n; b++) {
302 a * exp(-0.5 *
pow(
sqrt(
x[z] *
x[z] +
x[b] *
x[b]) / si, 2.0));
312 for (
Index i = 0; i < nf - 1; i++) {
327 r[0].set_name(
"Backend channel response function");
331 r[0].set_grid_name(0,
"Frequency");
332 x[1] = resolution / 2.0;
337 r[0].data[0] = 1 / resolution;
338 r[0].data[1] = r[0].data[0];
351 std::ostringstream os;
352 os <<
"*xwidth_si* and *dx_si* must have one element or the same number of\n";
353 os <<
"elements as *fwhm*.";
354 throw std::runtime_error(os.str());
361 Numeric this_xwidth_si = xwidth_si[0];
363 for (
Index i = 0; i < nchannels; i++) {
364 if (xwidth_si.
nelem() > 1) this_xwidth_si = xwidth_si[i];
366 if (dx_si.
nelem() > 1) this_dx_si = dx_si[i];
370 r[i].set_name(
"Backend channel response function");
372 r[i].set_grid_name(0,
"Frequency");
375 const Index n =
y.nelem();
377 for (
Index j = 0; j < n; j++) r[i].
data[j] =
y[j];
407 os <<
"There must be at least one channel.\n"
408 <<
"(The vector *lo* must have at least one element.)";
409 throw runtime_error(os.str());
416 os <<
"Variables *lo_multi*, *f_backend_multi* and *backend_channel_response_multi*\n"
417 <<
"must have same number of elements (number of LOs).";
418 throw runtime_error(os.str());
425 os <<
"Variables *f_backend_multi* and *backend_channel_response_multi*\n"
426 <<
"must have same number of bands for each LO.";
427 throw runtime_error(os.str());
436 Vector f_backend_flat(2 * n_chan);
450 f_backend_flat[j] = this_f_backend;
451 backend_channel_response_flat[j] = this_grid;
457 f_backend_flat[j] = f_image;
458 backend_channel_response_flat[j] = this_grid;
464 Vector fmin(2 * n_chan), fmax(2 * n_chan);
476 backend_channel_response_flat,
484 for (
Index i = 0; i < fmin.nelem(); ++i) {
486 const Numeric bw = fmax[i] - fmin[i];
489 const Numeric npf = ceil(bw / spacing);
499 out3 <<
" Band range " << i <<
": " << grid <<
"\n";
502 f_grid_array.reserve(f_grid_array.
nelem() + npi);
503 for (
Index s = 0; s < npi; ++s) f_grid_array.push_back(grid[s]);
509 out2 <<
" Total number of frequencies in f_grid: " <<
f_grid.nelem() <<
"\n";
523 const Vector& verbosityVect,
527 Index numFpoints = 0;
543 os <<
"There must be at least one channel.\n"
544 <<
"(The vector *lo* must have at least one element.)";
545 throw runtime_error(os.str());
553 Vector f_backend_flat(numChan);
558 Vector FminVerbosityVect(numFpoints);
559 Vector FmaxVerbosityVect(numFpoints);
560 Vector VerbosityValVect(numFpoints);
561 Index VerbVectIdx = 0;
568 f_backend_flat[i] = this_f_backend;
569 backend_channel_response_nonflat[i] = this_grid;
575 FminVerbosityVect[VerbVectIdx] =
578 VerbosityValVect[VerbVectIdx] = verbosityVect[i];
582 FmaxVerbosityVect[VerbVectIdx] =
605 backend_channel_response_nonflat,
615 const Numeric bw = fmax[i] - fmin[i];
616 Numeric npf = ceil(bw / spacing);
620 if (verbosityVect.
nelem() > 0) {
622 for (
Index ii = 0; ii < VerbVectIdx; ++ii) {
623 if ((FminVerbosityVect[ii] >= fmin[i]) &&
624 (FmaxVerbosityVect[ii] <= fmax[i])) {
628 if (VerbosityValVect[ii] < VerbosityValVect[verbIdx]) {
634 if (spacing > VerbosityValVect[verbIdx]) {
636 bw / VerbosityValVect[verbIdx]);
638 npf = ceil(bw / spacing);
650 Vector grid(fmin[i], npi, gs);
652 out3 <<
" Band range " << i <<
": " << grid <<
"\n";
655 f_grid_array.reserve(f_grid_array.
nelem() + npi);
656 for (
Index s = 0; s < npi; ++s) f_grid_array.push_back(grid[s]);
662 out2 <<
" Total number of frequencies in f_grid: " <<
f_grid.nelem() <<
"\n";
682 os <<
"Expected positive spacing. Found spacing to be: " << spacing <<
"\n";
683 throw runtime_error(os.str());
706 const Numeric bw = fmax[i] - fmin[i];
709 const Numeric npf = ceil(bw / spacing);
719 out3 <<
" Band range " << i <<
": " << grid <<
"\n";
722 f_grid_array.reserve(f_grid_array.
nelem() + npi);
723 for (
Index s = 0; s < npi; ++s) f_grid_array.push_back(grid[s]);
729 out2 <<
" Total number of frequencies in f_grid: " <<
f_grid.nelem() <<
"\n";
744 const Vector& freq_spacing,
746 const Numeric& freq_merge_threshold,
755 if (freq_spacing.
nelem() != 1 && freq_spacing.
nelem() != nchannels)
756 throw std::runtime_error(
757 "Length of *freq_spacing* vector must be either 1 or correspond\n"
758 "to the number of rows in *met_mm_backend*.");
760 if (freq_number.
nelem() != 1 && freq_number.
nelem() != nchannels)
761 throw std::runtime_error(
762 "Length of *freq_number* array must be either 1 or correspond\n"
763 "to the number of rows in *met_mm_backend*.");
765 if (freq_merge_threshold <= 0)
766 throw std::runtime_error(
"The *freq_merge_threshold* must be > 0.\n");
768 if (freq_merge_threshold > 100.)
769 throw std::runtime_error(
770 "The *freq_merge_threshold* is only meant to merge frequencies\n"
771 "that are basically identical and only differ slightly due to\n"
772 "numerical inaccuracies. Setting it to >100Hz is not reasonable.");
780 for (
Index ch = 0; ch < nchannels; ch++) {
782 const Numeric offset1 = mm_back(ch, 1);
783 const Numeric offset2 = mm_back(ch, 2);
784 const Numeric bandwidth = mm_back(ch, 3);
786 const Index this_fnumber =
787 (freq_number.
nelem() == 1) ? freq_number[0] : freq_number[ch];
789 (freq_spacing.
nelem() == 1) ? freq_spacing[0] : freq_spacing[ch];
791 if (this_spacing <= 0)
792 throw std::runtime_error(
"*freq_spacing must be > 0.");
794 if (this_fnumber == 0) {
796 os <<
"*freq_number* must be -1 or greater zero:"
797 <<
"freq_number[" << ch <<
"] = " << this_fnumber;
798 std::runtime_error(os.str());
803 1 + ((
Index)(offset1 > 0)) + (2 * (
Index)(offset2 > 0));
806 Index nfperband = this_fnumber;
808 if (this_fnumber == -1 ||
809 bandwidth / (
Numeric)this_fnumber > this_spacing) {
810 nfperband = (
Index)ceil(bandwidth / this_spacing);
814 nf_per_channel[ch] = npassb * nfperband;
821 for (
Index b = 0; b < npassb; b++) {
825 fc += (-1 + 2 * (
Numeric)b) * offset1;
826 }
else if (npassb == 4) {
832 if (b == 0 || b == 2) {
845 for (
size_t f_try = 0; f_try < f_grid_unsorted.size(); f_try++) {
846 if (
abs(fnew - f_grid_unsorted[f_try]) < freq_merge_threshold) {
848 index_in_unsorted.push_back(f_try);
853 f_grid_unsorted.push_back(fnew);
854 index_in_unsorted.push_back(f_grid_unsorted.size() - 1);
861 const size_t nf = f_grid_unsorted.size();
866 sorted_indices.resize(nf);
867 for (
size_t i = 0; i < nf; i++) {
868 sorted_indices[i] = i;
872 std::sort(sorted_indices.begin(),
873 sorted_indices.end(),
877 for (
size_t i = 0; i < nf; i++) {
878 move2index[sorted_indices[i]] = i;
892 for (
Index ch = 0; ch < nchannels; ch++) {
896 for (
Index j = 0; j < nf_per_channel[ch]; j++) {
916 w = spacing * ceil(width / spacing);
918 w = spacing * (0.5 + floor(width / spacing));
922 const Index l =
x.nelem();
924 Matrix dlos_try(l * l, 2, 0);
926 const Numeric c = width * width;
928 for (
Index i = 0; i < l; i++) {
931 for (
Index j = 0; j < l; j++) {
932 if (a +
x[j] *
x[j] <= c) {
933 dlos_try(n_in, 0) =
x[i];
934 dlos_try(n_in, 1) =
x[j];
956 w = spacing * ceil(za_width / spacing);
958 w = spacing * (0.5 + floor(za_width / spacing));
965 w = spacing * ceil(aa_width / spacing);
967 w = spacing * (0.5 + floor(aa_width / spacing));
978 for (
Index a = 0; a < naa; a++) {
979 for (
Index z = 0; z < nza; z++) {
1015 const Index nin = nf * npol * nlos;
1019 bool error_found =
false;
1023 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1024 <<
"grid variables (sensor_response_f_grid etc.).\n";
1028 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1029 <<
"right size compared to the sensor grid variables\n"
1030 <<
"(sensor_response_f_grid etc.).\n";
1036 os <<
"If *antenna_dim* is 2, *atmosphere_dim* must be 3.\n";
1041 if (
antenna_dlos.empty())
throw runtime_error(
"*antenna_dlos* is empty.");
1043 throw runtime_error(
"*antenna_dlos* must have one or 2 columns.");
1045 throw runtime_error(
1046 "*antenna_dlos* can only have two columns for 3D atmosphers.");
1052 const Index lpolgrid =
1055 if (lpolgrid != 1 && lpolgrid != npol) {
1056 os <<
"The number of polarisation in *antenna_response* must be 1 or be\n"
1057 <<
"equal to the number of polarisations used (determined by\n"
1058 <<
"*stokes_dim* or *instrument_pol*).\n";
1075 if (aresponse_f_grid.
nelem() > 1) {
1077 os <<
"The frequency grid of *antenna_response is too narrow. It must\n"
1078 <<
"cover all considered frequencies (*f_grid*), if the length\n"
1079 <<
"is > 1. The grid needs to be expanded with " << -f_dlow
1081 <<
"the lower end.\n";
1085 os <<
"The frequency grid of *antenna_response is too narrow. It must\n"
1086 <<
"cover all considered frequencies (*f_grid*), if the length\n"
1087 <<
"is > 1. The grid needs to be expanded with " << -f_dhigh
1089 <<
"the upper end.\n";
1101 if (aresponse_za_grid.
nelem() < 2) {
1102 os <<
"The zenith angle grid of *antenna_response* must have >= 2 values.\n";
1112 if (aresponse_aa_grid.
nelem() != 1) {
1113 os <<
"The azimuthal dimension of *antenna_response* must be 1 if\n"
1114 <<
"*antenna_dim* equals 1.\n";
1120 if (aresponse_za_grid.
nelem() < 2) {
1121 os <<
"The zenith angle grid of *antenna_response* must have >= 2\n"
1131 os <<
"For 1D antennas, the zenith angles in *sensor_response_dlos_grid*\n"
1132 <<
"must be sorted, either in increasing or decreasing order.\n"
1133 <<
"The original problem is probably found in *mblock_dlos_grid*.\n";
1148 os <<
"The WSV zenith angle part of *sensor_response_dlos_grid* is too narrow.\n"
1149 <<
"It should be expanded with " << -za_dlow
1150 <<
" deg in the lower end.\n"
1151 <<
"This change should be probably applied to *mblock_dlos_grid*.\n";
1155 os <<
"The WSV zenith angle part of *sensor_response_dlos_grid* is too narrow.\n"
1156 <<
"It should be expanded with " << -za_dhigh
1157 <<
" deg in the upper end.\n"
1158 <<
"This change should be probably applied to *mblock_dlos_grid*.\n";
1169 if (error_found)
throw runtime_error(os.str());
1189 if (option_2d ==
"interp_response" ) {
1198 else if (option_2d ==
"gridded_dlos" ) {
1209 throw runtime_error(
"Unrecognised choice for *option_2d*." );
1221 out3 <<
" Size of *sensor_response*: " <<
sensor_response.nrows() <<
"x"
1257 const Index nin = nf * npol * nlos;
1261 bool error_found =
false;
1265 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1266 <<
"grid variables (sensor_response_f_grid etc.).\n";
1270 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1271 <<
"right size compared to the sensor grid variables\n"
1272 <<
"(sensor_response_f_grid etc.).\n";
1278 os <<
"At least one value in *f_backend* (" <<
min(
f_backend)
1279 <<
") below range\ncovered by *sensor_response_f_grid* ("
1284 os <<
"At least one value in *f_backend* (" <<
max(
f_backend)
1285 <<
") above range\ncovered by *sensor_response_f_grid* ("
1294 if (nrp != 1 && nrp !=
f_backend.nelem()) {
1295 os <<
"The WSV *backend_channel_response* must have 1 or n elements,\n"
1296 <<
"where n is the length of *f_backend*.\n";
1302 if (error_found)
throw runtime_error(os.str());
1307 Index freq_full = nrp > 1;
1309 const Index irp = i * freq_full;
1314 os <<
"Mismatch in size of grid and data in element " << i
1315 <<
"\nof *sideband_response*.\n";
1320 os <<
"The frequency grid of element " << irp
1321 <<
" in *backend_channel_response*\nis not strictly increasing.\n";
1332 f_dlow =
min(f_dlow, f1);
1333 f_dhigh =
min(f_dhigh, f2);
1337 os <<
"The WSV *sensor_response_f_grid* is too narrow. It should be\n"
1338 <<
"expanded with " << -f_dlow <<
" Hz in the lower end. This change\n"
1339 <<
"should be applied to either *f_grid* or the sensor part in\n"
1340 <<
"front of *sensor_responseBackend*.\n";
1344 os <<
"The WSV *sensor_response_f_grid* is too narrow. It should be\n"
1345 <<
"expanded with " << -f_dhigh <<
" Hz in the higher end. This change\n"
1346 <<
"should be applied to either *f_grid* or the sensor part in\n"
1347 <<
"front of *sensor_responseBackend*.\n";
1353 if (error_found)
throw runtime_error(os.str());
1375 out3 <<
" Size of *sensor_response*: " <<
sensor_response.nrows() <<
"x"
1412 Vector f_backend_shifted;
1417 f_backend_shifted += df1;
1432 f_backend_shifted += df2;
1477 throw runtime_error(
1478 "This method requires that the number of observation directions is 2.");
1481 throw runtime_error(
1482 "This method handles (so far) only single polarisation cases.");
1487 Sparse Hbswitch(n, 2 * n);
1490 for (
Index i = 0; i < n; i++) {
1507 out3 <<
" Size of *sensor_response*: " <<
sensor_response.nrows() <<
"x"
1539 throw runtime_error(
1540 "This method requires that the number of observation directions is 1.");
1543 throw runtime_error(
1544 "This method handles (so far) only single polarisation cases.");
1547 const Index n2 = n / 2;
1550 throw runtime_error(
1551 "Assumptions of method are not fulfilled, "
1552 "considering number of rows in *sensor_response* "
1553 "and length of *sensor_response_f_grid*.");
1556 throw runtime_error(
1557 "There is an odd number of total frequencies, "
1558 "which is not consistent with the assumptions of "
1565 for (
Index i = 0; i < n2; i++) {
1582 out3 <<
" Size of *sensor_response*: " <<
sensor_response.nrows() <<
"x"
1613 throw runtime_error(
"The frequencies seem to already be given in RF.");
1631 throw runtime_error(
1632 "Only allowed options for *sideband _mode* are \"lower\" and \"upper\".");
1646 const Index& polyorder,
1655 const Index nin = nf * npol * nlos;
1659 bool error_found =
false;
1663 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1664 <<
"grid variables (sensor_response_f_grid etc.).\n";
1668 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1669 <<
"right size compared to the sensor grid variables\n"
1670 <<
"(sensor_response_f_grid etc.).\n";
1675 if (polyorder < 2 || polyorder > 7) {
1676 os <<
"Accepted range for *polyorder* is [3,7].\n";
1680 os <<
"The argument *nfill* must be > 1.\n";
1686 if (error_found)
throw runtime_error(os.str());
1690 const Index n1 = nfill + 1;
1691 const Index n2 = nfill + 2;
1692 const Index nnew = (nf - 1) * n1 + 1;
1696 for (
Index i = 0; i < nf - 1; i++) {
1699 fnew[
Range(i * n1, n2)] = fp;
1705 Matrix itw(nnew, polyorder + 1);
1712 Sparse hpoly(nnew * npol * nlos, nin);
1716 for (
Index ilos = 0; ilos < nlos; ilos++) {
1717 for (
Index iv = 0; iv < nnew; iv++) {
1718 for (
Index ip = 0; ip < npol; ip++) {
1719 const Index col0 = ilos * nf * npol;
1720 for (
Index i = 0; i < gp[iv].idx.
nelem(); i++) {
1722 if (
abs(
w) > 1e-5) {
1723 hrow[col0 + gp[iv].idx[i] * npol + ip] =
w;
1727 for (
Index i = 0; i < gp[iv].idx.
nelem(); i++) {
1728 hrow[col0 + gp[iv].idx[i] * npol + ip] = 0;
1743 out3 <<
" Size of *sensor_response*: " <<
sensor_response.nrows() <<
"x"
1787 throw runtime_error(
"*mblock_dlos_grid* is empty.");
1789 throw runtime_error(
1790 "The maximum number of columns in *mblock_dlos_grid* is two.");
1793 throw runtime_error(
1794 "For 1D and 2D *mblock_dlos_grid* must have exactly one column.");
1796 throw runtime_error(
1797 "2D antennas (antenna_dim=2) can only be "
1798 "used with 3D atmospheres.");
1823 out2 <<
" Initialising *sensor_reponse* as a identity matrix.\n";
1824 out3 <<
" Size of *sensor_response*: " << n <<
"x" << n <<
"\n";
1889 const Index nin = nf * npol * nlos;
1897 bool error_found =
false;
1901 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
1902 <<
"grid variables (sensor_response_f_grid etc.).\n";
1906 os <<
"The sensor block response matrix *sensor_response* does not have\n"
1907 <<
"right size compared to the sensor grid variables\n"
1908 <<
"(sensor_response_f_grid etc.).\n";
1914 os <<
"The given local oscillator frequency is outside the sensor\n"
1915 <<
"frequency grid. It must be within the *sensor_response_f_grid*.\n";
1921 os <<
"Mismatch in size of grid and data in *sideband_response*.\n";
1924 if (sbresponse_f_grid.
nelem() < 2) {
1925 os <<
"At least two data points must be specified in "
1926 <<
"*sideband_response*.\n";
1930 os <<
"The frequency grid of *sideband_response* must be strictly\n"
1934 if (fabs(
last(sbresponse_f_grid) + sbresponse_f_grid[0]) > 0) {
1935 os <<
"The end points of the *sideband_response* frequency grid must be\n"
1936 <<
"symmetrically placed around 0. That is, the grid shall cover a\n"
1937 <<
"a range that can be written as [-df,df]. \n";
1944 if (df_high > 0 && df_low > 0) {
1945 os <<
"The *sensor_response_f* grid must be extended by at least\n"
1946 << df_low <<
" Hz in the lower end and " << df_high <<
" Hz in the\n"
1947 <<
"upper end to cover frequency range set by *sideband_response*\n"
1948 <<
"and *lo*. Or can the frequency grid of *sideband_response* be\n"
1951 }
else if (df_high > 0) {
1952 os <<
"The *sensor_response_f* grid must be extended by at " << df_high
1953 <<
" Hz\nin the upper end to cover frequency range set by\n"
1954 <<
"*sideband_response* and *lo*. Or can the frequency grid of\n"
1955 <<
"*sideband_response* be decreased?";
1957 }
else if (df_low > 0) {
1958 os <<
"The *sensor_response_f* grid must be extended by at " << df_low
1959 <<
" Hz\nin the lower end to cover frequency range set by\n"
1960 <<
"*sideband_response* and *lo*. Or can the frequency grid of\n"
1961 <<
"*sideband_response* be decreased?";
1967 if (error_found)
throw runtime_error(os.str());
1991 out3 <<
" Size of *sensor_response*: " <<
sensor_response.nrows() <<
"x"
2033 const Index& use_antenna,
2034 const Index& mirror_dza,
2042 throw std::runtime_error(
2043 "So far inclusion of antenna pattern is NOT supported and\n"
2044 "*met_mm_antenna* must be empty.\n");
2047 throw std::runtime_error(
2048 "This method only supports 1D and 3D atmospheres.");
2051 throw std::runtime_error(
"*antenna_dlos* is empty.");
2054 throw std::runtime_error(
2055 "The maximum number of columns in *antenna_dlos*"
2059 Matrix antenna_dlos_local;
2064 throw std::runtime_error(
2065 "With *mirror_dza* set to true, *antenna_dlos*"
2066 "is only allowed to have a single column.");
2068 throw std::runtime_error(
"*mirror_dza* only makes sense in 3D.");
2072 for (
Index i = 0; i < n; i++) {
2077 antenna_dlos_local.
resize(n + nnew, 1);
2080 for (
Index i = n - 1; i >= 0; i--) {
2095 Sparse sensor_response_single;
2096 Matrix mblock_dlos_dummy(1, 1);
2097 mblock_dlos_dummy(0, 0) = 0;
2135 if (mm_pol.
nelem() != nchannels) {
2137 os <<
"Length of *met_mm_polarisation* (" << mm_pol.
nelem()
2139 <<
"number of channels in *met_mm_backend* (" << nchannels <<
").";
2140 throw std::runtime_error(os.str());
2144 Sparse sensor_response_tmp;
2146 for (
Index iza = 0; iza < antenna_dlos_local.
nrows(); iza++) {
2147 sensor_response_tmp =
Sparse(nchannels, sensor_response_single.
ncols());
2150 mult(sensor_response_tmp, H_pol, sensor_response_single);
2151 for (
Index r = 0; r < sensor_response_tmp.
nrows(); r++)
2152 for (
Index c = 0; c < sensor_response_tmp.
ncols(); c++) {
2153 const Numeric v = sensor_response_tmp(r, c);
2162 for (
Index iza = 0; iza < antenna_dlos_local.
nrows(); iza++) {
2163 for (
Index r = 0; r < sensor_response_single.
nrows(); r++)
2164 for (
Index c = 0; c < sensor_response_single.
ncols(); c++) {
2165 const Numeric v = sensor_response_single(r, c);
2178 throw std::runtime_error(
"The antenna hasn't arrived yet.");
2218 const Index nin = nin_f * npol * nlos;
2219 const Index nout = nout_f * npol * nlos;
2223 bool error_found =
false;
2227 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
2228 <<
"grid variables (sensor_response_f_grid etc.).\n";
2232 os <<
"The sensor block response matrix *sensor_response* does not have\n"
2233 <<
"right size compared to the sensor grid variables\n"
2234 <<
"(sensor_response_f_grid etc.).\n";
2240 os <<
"*f_backend* is empty !!!\n";
2244 os <<
"At least one value in *f_backend* (" <<
min(
f_backend)
2245 <<
") below range\ncovered by *sensor_response_f_grid* ("
2250 os <<
"At least one value in *f_backend* (" <<
max(
f_backend)
2251 <<
") above range\ncovered by *sensor_response_f_grid* ("
2258 os <<
"The first size of *channel2fgrid_indexes* an length of *f_backend* "
2259 <<
"must be equal.\n";
2263 os <<
"Leading sizes of *channel2fgrid_indexes* and "
2264 <<
"*channel2fgrid_weights* differ.\n";
2267 for (
Index i = 0; i < nout_f; i++) {
2269 os <<
"Mismatch in size between *channel2fgrid_indexes* and "
2270 <<
"*channel2fgrid_weights*, found for array/vector with "
2271 <<
"index " << i <<
".\n";
2277 os <<
"At least one value in *channel2fgrid_indexes* is either "
2278 <<
" < 0 or is too high considering length of "
2279 <<
"*sensor_response_f_grid*.\n";
2287 if (error_found)
throw runtime_error(os.str());
2294 for (
Index ifr = 0; ifr < nout_f; ifr++) {
2304 for (
Index sp = 0; sp < nlos; sp++) {
2305 for (
Index pol = 0; pol < npol; pol++) {
2307 Vector weights_long(nin, 0.0);
2308 weights_long[
Range(sp * nin_f * npol + pol, nin_f, npol)] = w1;
2311 hmb.
insert_row(sp * nout_f * npol + ifr * npol + pol, weights_long);
2358 const Index nin = nf * npol * nlos;
2363 bool error_found =
false;
2367 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
2368 <<
"grid variables (sensor_response_f_grid etc.).\n";
2372 os <<
"The sensor block response matrix *sensor_response* does not have\n"
2373 <<
"right size compared to the sensor grid variables\n"
2374 <<
"(sensor_response_f_grid etc.).\n";
2381 os <<
"Inconsistency in length between *lo_mixer* and "
2382 <<
"*sideband_response_multi*.\n";
2386 os <<
"Inconsistency in length between *lo_mixer* and "
2387 <<
"*sideband_mode_multi*.\n";
2391 os <<
"Inconsistency in length between *lo_mixer* and "
2392 <<
"*f_backend_multi*.\n";
2396 os <<
"Inconsistency in length between *lo_mixer* and "
2397 <<
"*backend_channel_response_multi*.\n";
2403 if (error_found)
throw runtime_error(os.str());
2410 for (
Index ilo = 0; ilo < nlo; ilo++) {
2447 }
catch (
const runtime_error& e) {
2449 os2 <<
"Error when dealing with receiver/mixer chain (1-based index) "
2452 throw runtime_error(os2.str());
2457 srfgrid.push_back(srfgrid1);
2459 cumsumf[ilo + 1] = cumsumf[ilo] + srfgrid1.
nelem();
2464 const Index nfnew = cumsumf[nlo];
2467 for (
Index ilo = 0; ilo < nlo; ilo++) {
2468 for (
Index i = 0; i < srfgrid[ilo].
nelem(); i++) {
2477 const Index nfpolnew = nfnew * npolnew;
2483 for (
Index ilo = 0; ilo < nlo; ilo++) {
2484 const Index nfpolthis = (cumsumf[ilo + 1] - cumsumf[ilo]) * npolnew;
2486 assert(sr[ilo].
nrows() == nlos * nfpolthis);
2489 for (
Index ilos = 0; ilos < nlos; ilos++) {
2490 for (
Index i = 0; i < nfpolthis; i++) {
2493 dummy[ic] = sr[ilo](ilos * nfpolthis + i, ic);
2496 sensor_response.insert_row(ilos * nfpolnew + cumsumf[ilo] * npolnew + i,
2533 bool error_found =
false;
2535 Index nfz = nf * nlos;
2536 Index nin = nfz * npol;
2539 os <<
"The sensor block response matrix *sensor_response* does not have\n"
2540 <<
"right size compared to the sensor grid variables\n"
2541 <<
"(sensor_response_f_grid etc.).\n";
2547 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
2548 <<
"grid variables (sensor_response_f_grid etc.).\n";
2552 os <<
"Number of input polarisation does not match *stokes_dim*.\n";
2556 os <<
"The WSV *instrument_pol* can not be empty.\n";
2561 if (error_found)
throw runtime_error(os.str());
2564 for (
Index i = 0; i < npol && !error_found; i++) {
2566 os <<
"The input polarisations must be I, Q, U and V (up to "
2567 <<
"stokes_dim). It seems that input data are for other "
2568 <<
"polarisation components.";
2572 for (
Index i = 0; i < nnew && !error_found; i++) {
2574 os <<
"The elements of *instrument_pol* must be inside the range [1,10].\n";
2580 if (error_found)
throw runtime_error(os.str());
2584 if (error_found)
throw runtime_error(os.str());
2594 Sparse Hpol(nfz * nnew, nin);
2598 for (
Index i = 0; i < nfz; i++) {
2599 Index col = i * npol;
2600 for (
Index in = 0; in < nnew; in++) {
2653 const Index nin = nf * npol * nlos;
2658 bool error_found =
false;
2662 os <<
"The sensor block response matrix *sensor_response* does not have\n"
2663 <<
"right size compared to the sensor grid variables\n"
2664 <<
"(sensor_response_f_grid etc.).\n";
2670 os <<
"To perform a rotation of the Stokes coordinate system,\n"
2671 <<
"*stokes_dim* must be >= 3.\n";
2675 os <<
"Incorrect number of angles in *stokes_rotation*. The length\n"
2676 <<
"of this matrix must match *sensor_response_dlos_grid*.\n";
2680 os <<
"Inconsistency detected. The length of *sensor_response_pol_grid*\n"
2681 <<
"must be equal to *stokes_dim*, and this is not the case.\n";
2684 for (
Index is = 0; is < npol; is++) {
2686 os <<
"For this method, the values in *sensor_response_pol_grid* must\n"
2687 <<
"be 1,2...stokes_dim. This is not the case, indicating that\n"
2688 <<
"some previous sensor part has that the data no longer are\n"
2689 <<
"Stokes vectors.\n";
2697 if (error_found)
throw runtime_error(os.str());
2708 for (
Index ilos = 0; ilos < nlos; ilos++) {
2712 for (
Index ifr = 0; ifr < nf; ifr++) {
2713 for (
Index ip = 0; ip < npol; ip++) {
2716 for (
Index is = 0; is < npol; is++) {
2717 row[irow + is] = Hrot.
ro(ip, is);
2721 for (
Index is = 0; is < npol; is++) {
2775 os <<
"Input variable sensor_description_amsu must have atleast five columns, but it has "
2777 throw runtime_error(os.str());
2789 const Numeric minRatioVerbosityVsFdiff =
2794 for (
Index idx = 0; idx < n; ++idx) {
2795 if ((verbosityVectIn[idx] == 0) || (verbosityVectIn[idx] > width[idx])) {
2796 verbosityVect[idx] = ((
Numeric)width[idx]) / 3;
2798 verbosityVect[idx] = verbosityVectIn[idx];
2806 for (
Index i = 0; i < n; ++i) {
2808 for (
Index j = 0; j < (m - 2); ++j) {
2810 if (offset(i, j) > 0) {
2815 numPB[i] = 1 << (int)numPB[i];
2816 if (numPB[i] == 1) {
2819 numPBpseudo[i] = numPB[i];
2822 totNumPb += (int)numPB[i];
2826 os <<
"This function does currently not support more than 4 passbands per channel"
2828 throw runtime_error(os.str());
2836 for (
Index i = 0; i < n; ++i) {
2840 f[0] =
lo_multi[i] + 0.0 * width[i];
2843 const Index numVal = 4;
2846 b_resp.
set_name(
"Backend channel response function");
2847 b_resp.
resize(numVal * numPBpseudo[i]);
2848 Vector f_range(numVal * numPBpseudo[i]);
2854 for (
Index pbOffsetIdx = 0; pbOffsetIdx < numPBpseudo[i];
2856 slope = width[i] / 100;
2857 f_range[pbOffsetIdx * numVal + 0] = -0.5 * width[i] - 0 * slope;
2858 f_range[pbOffsetIdx * numVal + 1] = -0.5 * width[i] + 1 * slope;
2859 f_range[pbOffsetIdx * numVal + 2] = +0.5 * width[i] - 1 * slope;
2860 f_range[pbOffsetIdx * numVal + 3] = +0.5 * width[i] + 0 * slope;
2862 b_resp.
data[pbOffsetIdx * numVal + 0] = 0.0 / (
Numeric)numPB[i];
2864 b_resp.
data[pbOffsetIdx * numVal + 1] = 1.0 / (
Numeric)numPB[i];
2865 b_resp.
data[pbOffsetIdx * numVal + 2] = 1.0 / (
Numeric)numPB[i];
2866 b_resp.
data[pbOffsetIdx * numVal + 3] = 0.0 / (
Numeric)numPB[i];
2868 if (numPB[i] == 1) {
2869 if (pbOffsetIdx == 0) {
2870 pbOffset = -0.0 * width[i];
2871 b_resp.
data[pbOffsetIdx * numVal + 0] = 0;
2872 b_resp.
data[pbOffsetIdx * numVal + 1] = 1.0 / 1;
2874 b_resp.
data[pbOffsetIdx * numVal + 2] = 1.0 / 1;
2875 b_resp.
data[pbOffsetIdx * numVal + 3] = 1.0 / 1;
2876 f_range[pbOffsetIdx * numVal + 0] = -0.5 * width[i] - 2 * slope;
2877 f_range[pbOffsetIdx * numVal + 1] = -0.5 * width[i] - 1 * slope;
2878 f_range[pbOffsetIdx * numVal + 2] = -0.5 * width[i] + 1 * slope;
2879 f_range[pbOffsetIdx * numVal + 3] = -0.5 * width[i] + 2 * slope;
2881 if (pbOffsetIdx == 1) {
2882 pbOffset = 0.0 * width[i];
2883 b_resp.
data[pbOffsetIdx * numVal + 0] = 1.0 / 1;
2884 b_resp.
data[pbOffsetIdx * numVal + 1] = 1.0 / 1;
2885 b_resp.
data[pbOffsetIdx * numVal + 2] = 1.0 / 1;
2886 b_resp.
data[pbOffsetIdx * numVal + 3] = 0;
2887 f_range[pbOffsetIdx * numVal + 0] = +0.5 * width[i] - 3 * slope;
2888 f_range[pbOffsetIdx * numVal + 1] = +0.5 * width[i] - 2 * slope;
2889 f_range[pbOffsetIdx * numVal + 2] = +0.5 * width[i] - 1 * slope;
2890 f_range[pbOffsetIdx * numVal + 3] = +0.5 * width[i] + 0 * slope - 10;
2896 if (pbOffsetIdx == 0) {
2897 pbOffset = -offset(i, 0);
2899 if (pbOffsetIdx == 1) {
2900 pbOffset = offset(i, 0);
2903 if (numPB[i] == 4) {
2904 if (pbOffsetIdx == 0) {
2905 pbOffset = -offset(i, 0) - offset(i, 1);
2907 if (pbOffsetIdx == 1) {
2908 pbOffset = -offset(i, 0) + offset(i, 1);
2910 if (pbOffsetIdx == 2) {
2911 pbOffset = offset(i, 0) - offset(i, 1);
2913 if (pbOffsetIdx == 3) {
2914 pbOffset = offset(i, 0) + offset(i, 1);
2917 for (
Index iii = 0; iii < numVal; ++iii) {
2918 f_range[pbOffsetIdx * numVal + iii] += 1 * pbOffset;
2922 for (
Index ii = 2; ii < (f_range.
nelem() - 2); ++ii) {
2923 if (((b_resp.
data[ii - 1] == 1) && (b_resp.
data[ii] == 0) &&
2924 (b_resp.
data[ii + 1] == 0) && (b_resp.
data[ii + 2] == 1))) {
2925 if ((f_range[ii] >= f_range[ii + 1]))
2927 if ((f_range[ii + 2] - f_range[ii - 1]) >
2930 f_range[ii + 1] = f_range[ii + 2] - verbosityVectIn[i] / 2;
2931 f_range[ii] = f_range[ii - 1] + verbosityVectIn[i] / 2;
2933 f_range[ii - 1] = (f_range[ii] + f_range[ii + 2]) / 2 -
2934 2 * verbosityVectIn[i] / minRatioVerbosityVsFdiff;
2935 f_range[ii + 1] = (f_range[ii] + f_range[ii + 2]) / 2 +
2936 verbosityVectIn[i] / minRatioVerbosityVsFdiff;
2938 f_range[ii - 1] + verbosityVectIn[i] / minRatioVerbosityVsFdiff;
2940 f_range[ii + 1] + verbosityVectIn[i] / minRatioVerbosityVsFdiff;
2950 for (
Index i = 0; i < n; ++i) {
2952 r.
set_name(
"Sideband response function");
2953 r.
resize(numPBpseudo[i]);
2954 Vector f(numPBpseudo[i]);
2955 if (numPB[i] == 1) {
2957 f[0] = -.0 * width[i];
2959 f[1] = .0 * width[i];
2960 }
else if (numPB[i] == 2) {
2963 f[0] = -1 * offset(i, 0) - 0.5 * width[i];
2964 f[1] = +1 * offset(i, 0) + 0.5 * width[i];
2965 }
else if (numPB[i] == 4) {
2970 f[0] = -offset(i, 0) - offset(i, 1) - 0.5 * width[i];
2972 f[1] = -offset(i, 0) + offset(i, 1) - 0.5 * width[i];
2974 f[2] = +offset(i, 0) - offset(i, 1) + 0.5 * width[i];
2976 f[3] = +offset(i, 0) + offset(i, 1) + 0.5 * width[i];
3024 for (
Index idxLO = 0; idxLO < numLO; idxLO++) {
3047 srfgrid.push_back(srfgrid1);
3049 cumsumf[idxLO + 1] = cumsumf[idxLO] + srfgrid1.
nelem();
3054 const Index nfnew = cumsumf[numLO];
3057 for (
Index ilo = 0; ilo < numLO; ilo++) {
3058 for (
Index i = 0; i < srfgrid[ilo].
nelem(); i++) {
3065 const Index nfpolnew = nfnew * npolnew;
3071 for (
Index ilo = 0; ilo < numLO; ilo++) {
3072 const Index nfpolthis = (cumsumf[ilo + 1] - cumsumf[ilo]) * npolnew;
3074 assert(sr[ilo].
nrows() == nlos * nfpolthis);
3077 for (
Index ilos = 0; ilos < nlos; ilos++) {
3078 for (
Index i = 0; i < nfpolthis; i++) {
3081 dummy[ic] = sr[ilo](ilos * nfpolthis + i, ic);
3084 sensor_response.insert_row(ilos * nfpolnew + cumsumf[ilo] * npolnew + i,
3123 os <<
"Input variable sensor_description_amsu must have three columns, but it has "
3125 throw runtime_error(os.str());
3140 for (
Index i = 0; i < n; ++i) {
3148 for (
Index i = 0; i < n; ++i) {
3151 r.
set_name(
"Backend channel response function");
3156 f[0] = -0.5 * width[i];
3157 f[1] = +0.5 * width[i];
3168 for (
Index i = 0; i < n; ++i) {
3170 r.
set_name(
"Sideband response function");
3175 f[0] = -(offset[i] + 0.5 * width[i]);
3176 f[1] = +(offset[i] + 0.5 * width[i]);
3255 os <<
"The WSV *wmrf_weights* must have same number of rows as\n"
3256 <<
"*f_backend*, and same number of columns as *f_grid*.\n"
3257 <<
"wmrf_weights.nrows() = " <<
wmrf_weights.nrows() <<
"\n"
3258 <<
"f_backend.nelem() = " <<
f_backend.nelem() <<
"\n"
3259 <<
"wmrf_weights.ncols() = " <<
wmrf_weights.ncols() <<
"\n"
3260 <<
"f_grid.nelem() = " <<
f_grid.nelem();
3261 throw runtime_error(os.str());
3274 os <<
"Max(wmrf_channels) must be less than the total number of channels.\n"
3275 <<
"(We use zero-based indexing!)\n"
3281 out2 <<
" Retaining all channels.\n";
3283 out2 <<
" Reducing number of channels from " <<
f_backend.nelem() <<
" to "
3306 selection.reserve(
f_grid.nelem());
3316 selection.push_back(fi);
3321 out3 <<
" The frequency with index " << fi
3322 <<
" is not used by any channel.\n";
3328 out2 <<
" No unnecessary frequencies, leaving f_grid untouched.\n";
3329 }
else if (selection.
nelem() == 0) {
3330 throw runtime_error(
"No frequencies found for any selected channels.\n");
3332 out2 <<
" Reducing number of frequency grid points from " <<
f_grid.nelem()
3333 <<
" to " << selection.
nelem() <<
".\n";
3370 const Index nin = nf * npol * nlos;
3374 bool error_found =
false;
3378 os <<
"Inconsistency in size between *sensor_response_f* and the sensor\n"
3379 <<
"grid variables (sensor_response_f_grid etc.).\n";
3383 os <<
"The sensor block response matrix *sensor_response* does not have\n"
3384 <<
"right size compared to the sensor grid variables\n"
3385 <<
"(sensor_response_f_grid etc.).\n";
3390 os <<
"One of f_grid, pol_grid, dlos_grid are empty. Sizes are: (" << nf
3391 <<
", " << npol <<
", " << nlos <<
")"
3401 os <<
"The WSV *wmrf_weights* must have as many rows\n"
3402 <<
"as *f_backend* has elements.\n"
3403 <<
"wmrf_weights.nrows() = " << nrw <<
"\n"
3404 <<
"f_backend.nelem() = " <<
f_backend.nelem() <<
"\n";
3413 os <<
"The WSV *wmrf_weights* must have as many columns\n"
3414 <<
"as *sensor_response_f_grid* has elements.\n"
3415 <<
"wmrf_weights.ncols() = " << ncw <<
"\n"
3423 if (error_found)
throw runtime_error(os.str());
3435 out3 <<
" Size of *sensor_response*: " <<
sensor_response.nrows() <<
"x"
3545 const Index n1 =
y.nelem();
3548 const Index n2 = nm * nc;
3551 if (
y.empty())
throw runtime_error(
"Input *y* is empty. Use *yCalc*");
3552 if (
y_f.nelem() != n1)
3553 throw runtime_error(
"Lengths of input *y* and *y_f* are inconsistent.");
3554 if (
y_pol.nelem() != n1)
3555 throw runtime_error(
"Lengths of input *y* and *y_pol* are inconsistent.");
3556 if (
y_pos.nrows() != n1)
3557 throw runtime_error(
"Sizes of input *y* and *y_pos* are inconsistent.");
3558 if (
y_los.nrows() != n1)
3559 throw runtime_error(
"Sizes of input *y* and *y_los* are inconsistent.");
3560 if (
y_geo.nrows() != n1)
3561 throw runtime_error(
"Sizes of input *y* and *y_geo* are inconsistent.");
3564 throw runtime_error(
"Sizes of *y* and *jacobian* are inconsistent.");
3569 throw runtime_error(
3570 "*stokes_dim* must be >= 3 to correctly apply a "
3571 "polarisation rotation.");
3573 throw runtime_error(
"Length of input *y* smaller than *stokes_dim*.");
3575 if (
y_pol[i] != i + 1)
3576 throw runtime_error(
3577 "*y* must hold Stokes element values. Data in "
3578 "*y_pol* indicates that this is not the case.");
3583 throw runtime_error(
3584 "Different number of rows in *sensor_pos* and *sensor_pol*.");
3586 throw runtime_error(
3587 "Number of columns in *sensor_pol* not consistent with "
3588 "length of *y* and value of *stokes_dim*.");
3605 y_los.resize(n2, y_los1.ncols());
3606 y_geo.resize(n2, y_geo1.ncols());
3612 for (
Index r = 0; r < nm; r++) {
3613 for (
Index c = 0; c < nc; c++) {
3614 const Index iout = r * nc + c;
3621 y[iout] = y1[iin] + wq * y1[iin + 1] + wu * y1[iin + 2];
3626 jacobian(iout,
q) = jacobian1(iin,
q) + wq * jacobian1(iin + 1,
q) +
3627 wu * jacobian1(iin + 2,
q);
3634 y_f[iout] = y_f1[iin];
3638 for (
Index a = 0; a <
y_aux.nelem(); a++)
y_aux[a][iout] = y_aux1[a][iin];
void sensor_responseMixer(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Numeric &lo, const GriddedField1 &sideband_response, const Index &sensor_norm, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseMixer.
Matrix y_pos(Workspace &ws) noexcept
Index atmosphere_dim(Workspace &ws) noexcept
ArrayOfVector y_aux(Workspace &ws) noexcept
Vector lo_multi(Workspace &ws) noexcept
void sensor_responseMultiMixerBackend(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Vector &lo_multi, const ArrayOfGriddedField1 &sideband_response_multi, const ArrayOfString &sideband_mode_multi, const ArrayOfVector &f_backend_multi, const ArrayOfArrayOfGriddedField1 &backend_channel_response_multi, const Index &sensor_norm, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseMultiMixerBackend.
void backend_channel_responseFlat(ArrayOfGriddedField1 &r, const Numeric &resolution, const Verbosity &)
WORKSPACE METHOD: backend_channel_responseFlat.
void set_grid_name(Index i, const String &s)
Set grid name.
void f_gridFromSensorAMSUgeneric(Vector &f_grid, const ArrayOfVector &f_backend_multi, const ArrayOfArrayOfGriddedField1 &backend_channel_response_multi, const Numeric &spacing, const Vector &verbosityVect, const Verbosity &verbosity)
WORKSPACE METHOD: f_gridFromSensorAMSUgeneric.
Matrix sensor_response_dlos_grid(Workspace &ws) noexcept
void resize(Index b, Index p, Index r, Index c)
Resize function.
void ySimpleSpectrometer(Vector &y, Vector &y_f, const Matrix &iy, const Index &stokes_dim, const Vector &f_grid, const Numeric &df, const Verbosity &verbosity)
WORKSPACE METHOD: ySimpleSpectrometer.
Matrix antenna_dlos(Workspace &ws) noexcept
const Numeric SPEED_OF_LIGHT
void find_effective_channel_boundaries(Vector &fmin, Vector &fmax, const Vector &f_backend, const ArrayOfGriddedField1 &backend_channel_response, const Numeric &delta, const Verbosity &verbosity)
Calculate channel boundaries from instrument response functions.
void f_gridFromSensorAMSU(Vector &f_grid, const Vector &lo, const ArrayOfVector &f_backend, const ArrayOfArrayOfGriddedField1 &backend_channel_response, const Numeric &spacing, const Verbosity &verbosity)
WORKSPACE METHOD: f_gridFromSensorAMSU.
void gaussian_response_autogrid(Vector &x, Vector &y, const Numeric &x0, const Numeric &fwhm, const Numeric &xwidth_si, const Numeric &dx_si)
gaussian_response_autogrid
ArrayOfVector channel2fgrid_weights(Workspace &ws) noexcept
ArrayOfIndex instrument_pol(Workspace &ws) noexcept
Sparse wmrf_weights(Workspace &ws) noexcept
Numeric lo(Workspace &ws) noexcept
Index ncols() const
Returns the number of columns.
Complex w(Complex z) noexcept
The Faddeeva function.
void sensor_responseSimpleAMSU(Vector &f_grid, Index &antenna_dim, Matrix &mblock_dlos_grid, Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, ArrayOfIndex &sensor_response_pol_grid, Matrix &sensor_response_dlos_grid, Index &sensor_norm, const Index &atmosphere_dim, const Index &stokes_dim, const Matrix &sensor_description_amsu, const Numeric &spacing, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseSimpleAMSU.
void gridpos(ArrayOfGridPos &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Numeric &extpolfac)
Set up a grid position Array.
void mblock_dlos_gridUniformCircular(Matrix &mblock_dlos_grid, const Numeric &spacing, const Numeric &width, const Index ¢re, const Verbosity &)
WORKSPACE METHOD: mblock_dlos_gridUniformCircular.
void antenna2d_gridded_dlos(Sparse &H, const Index &antenna_dim, ConstMatrixView antenna_dlos, const GriddedField4 &antenna_response, ConstMatrixView mblock_dlos, ConstVectorView f_grid, const Index n_pol)
antenna2d_interp_gridded_dlos
void spectrometer_matrix(Sparse &H, ConstVectorView ch_f, const ArrayOfGriddedField1 &ch_response, ConstVectorView sensor_f, const Index &n_pol, const Index &n_sp, const Index &do_norm)
spectrometer_matrix
void sensor_responseMixerBackendPrecalcWeights(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Vector &f_backend, const ArrayOfArrayOfIndex &channel2fgrid_indexes, const ArrayOfVector &channel2fgrid_weights, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseMixerBackendPrecalcWeights.
void id_mat(MatrixView I)
Identity Matrix.
Sparse sensor_response(Workspace &ws) noexcept
void backend_channel_responseGaussian(ArrayOfGriddedField1 &r, const Vector &fwhm, const Vector &xwidth_si, const Vector &dx_si, const Verbosity &)
WORKSPACE METHOD: backend_channel_responseGaussian.
ArrayOfGriddedField1 backend_channel_response(Workspace &ws) noexcept
void antenna1d_matrix(Sparse &H, const Index &antenna_dim, ConstVectorView antenna_dza, const GriddedField4 &antenna_response, ConstVectorView za_grid, ConstVectorView f_grid, const Index n_pol, const Index do_norm)
antenna1d_matrix
void antenna2d_interp_response(Sparse &H, const Index &antenna_dim, ConstMatrixView antenna_dlos, const GriddedField4 &antenna_response, ConstMatrixView mblock_dlos, ConstVectorView f_grid, const Index n_pol)
antenna2d_interp_response
void AntennaConstantGaussian1D(Index &antenna_dim, Matrix &mblock_dlos_grid, GriddedField4 &r, Matrix &antenna_dlos, const Index &n_za_grid, const Numeric &fwhm, const Numeric &xwidth_si, const Numeric &dx_si, const Verbosity &verbosity)
WORKSPACE METHOD: AntennaConstantGaussian1D.
const Index GFIELD1_F_GRID
void mblock_dlos_gridUniformRectangular(Matrix &mblock_dlos_grid, const Numeric &spacing, const Numeric &za_width, const Numeric &aa_width, const Index ¢re, const Verbosity &)
WORKSPACE METHOD: mblock_dlos_gridUniformRectangular.
Numeric last(ConstVectorView x)
last
Numeric interp(ConstVectorView itw, ConstVectorView a, const GridPos &tc)
Red 1D Interpolate.
GriddedField4 antenna_response(Workspace &ws) noexcept
void sensor_responseFrequencySwitching(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseFrequencySwitching.
Verbosity verbosity(Workspace &ws) noexcept
void mult(ComplexVectorView y, const ConstComplexMatrixView &M, const ConstComplexVectorView &x)
Matrix-Vector Multiplication.
GriddedField1 sideband_response(Workspace &ws) noexcept
const Index GFIELD4_ZA_GRID
Index f_index(Workspace &ws) noexcept
void gaussian_response(Vector &y, const Vector &x, const Numeric &x0, const Numeric &fwhm)
gaussian_response
Index jacobian_do(Workspace &ws) noexcept
Vector y(Workspace &ws) noexcept
void resize(Index n)
Resize function.
Matrix y_los(Workspace &ws) noexcept
Index antenna_dim(Workspace &ws) noexcept
G0 G2 FVC Y DV Numeric Numeric Numeric Zeeman LowerQuantumNumbers void * data
Index stokes_dim(Workspace &ws) noexcept
Index nrows() const
Returns the number of rows.
Numeric ro(Index r, Index c) const
Read only index operator.
String iy_unit(Workspace &ws) noexcept
void AntennaMultiBeamsToPencilBeams(Matrix &sensor_pos, Matrix &sensor_los, Matrix &antenna_dlos, Index &antenna_dim, Matrix &mblock_dlos_grid, const Index &atmosphere_dim, const Verbosity &verbosity)
WORKSPACE METHOD: AntennaMultiBeamsToPencilBeams.
Matrix iy(Workspace &ws) noexcept
void AntennaOff(Index &antenna_dim, Matrix &mblock_dlos_grid, const Verbosity &verbosity)
WORKSPACE METHOD: AntennaOff.
ArrayOfArrayOfIndex channel2fgrid_indexes(Workspace &ws) noexcept
void antenna_responseGaussian(GriddedField4 &r, const Numeric &fwhm, const Numeric &xwidth_si, const Numeric &dx_si, const Index &do_2d, const Verbosity &)
WORKSPACE METHOD: antenna_responseGaussian.
Numeric sqrt(const Rational r)
Square root.
void insert_row(Index r, Vector v)
Insert row function.
void sensor_responseFillFgrid(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Index &polyorder, const Index &nfill, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseFillFgrid.
void sensor_responseBackendFrequencySwitching(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Vector &f_backend, const ArrayOfGriddedField1 &backend_channel_response, const Index &sensor_norm, const Numeric &df1, const Numeric &df2, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseBackendFrequencySwitching.
This can be used to make arrays out of anything.
Numeric pow(const Rational base, Numeric exp)
Power of.
bool is_decreasing(ConstVectorView x)
Checks if a vector is sorted in reversed order and is strictly decreasing.
Index nelem(const Lines &l)
Number of lines.
const Index GFIELD4_FIELD_NAMES
Vector sensor_response_f(Workspace &ws) noexcept
Sensor modelling functions.
void met_mm_polarisation_hmatrix(Sparse &H, const ArrayOfString &mm_pol, const Numeric dza, const Index stokes_dim, const String &iy_unit)
Calculate polarisation H-matrix.
void sensor_responseIF2RF(Vector &sensor_response_f, Vector &sensor_response_f_grid, const Numeric &lo, const String &sideband_mode, const Verbosity &)
WORKSPACE METHOD: sensor_responseIF2RF.
const Vector & get_numeric_grid(Index i) const
Get a numeric grid.
void sensorOff(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, ArrayOfIndex &sensor_response_pol_grid, Matrix &sensor_response_dlos_grid, Matrix &mblock_dlos_grid, const Index &stokes_dim, const Vector &f_grid, const Verbosity &verbosity)
WORKSPACE METHOD: sensorOff.
Declarations having to do with the four output streams.
void sensor_responseBackend(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Vector &f_backend, const ArrayOfGriddedField1 &backend_channel_response, const Index &sensor_norm, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseBackend.
Vector y_f(Workspace &ws) noexcept
Index ncols() const
Returns the number of columns.
ArrayOfIndex y_pol(Workspace &ws) noexcept
void sensor_responseAntenna(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Matrix &sensor_response_dlos_grid, const Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Index &atmosphere_dim, const Index &antenna_dim, const Matrix &antenna_dlos, const GriddedField4 &antenna_response, const Index &sensor_norm, const String &option_2d, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseAntenna.
Matrix sensor_pol(Workspace &ws) noexcept
void sub(Sparse &A, const Sparse &B, const Sparse &C)
Sparse - Sparse subtraction.
Index nelem() const
Returns the number of elements.
NUMERIC Numeric
The type to use for all floating point numbers.
Vector iyb(Workspace &ws) noexcept
void set_name(const String &s)
Set name of this gridded field.
ArrayOfVector f_backend_multi(Workspace &ws) noexcept
Vector f_backend(Workspace &ws) noexcept
Vector f_grid(Workspace &ws) noexcept
Matrix sensor_pos(Workspace &ws) noexcept
void antenna_responseVaryingGaussian(GriddedField4 &r, const Numeric &leff, const Numeric &xwidth_si, const Numeric &dx_si, const Index &nf, const Numeric &fstart, const Numeric &fstop, const Index &do_2d, const Verbosity &verbosity)
WORKSPACE METHOD: antenna_responseVaryingGaussian.
Vector sensor_response_f_grid(Workspace &ws) noexcept
void resize(Index r, Index c)
Resize function.
Header file for interpolation_poly.cc.
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
nlinspace
A constant view of a Matrix.
ArrayOfArrayOfGriddedField1 backend_channel_response_multi(Workspace &ws) noexcept
Index nrows(Workspace &ws) noexcept
invlib::Vector< ArtsVector > Vector
invlib wrapper type for ARTS vectors.
Matrix mblock_dlos_grid(Workspace &ws) noexcept
ArrayOfIndex sensor_response_pol(Workspace &ws) noexcept
const Index GFIELD4_AA_GRID
void set_grid(Index i, const Vector &g)
Set a numeric grid.
Propagation path structure and functions.
void mixer_matrix(Sparse &H, Vector &f_mixer, const Numeric &lo, const GriddedField1 &filter, ConstVectorView f_grid, const Index &n_pol, const Index &n_sp, const Index &do_norm)
mixer_matrix
ArrayOfIndex sensor_response_pol_grid(Workspace &ws) noexcept
bool is_increasing(ConstVectorView x)
Checks if a vector is sorted and strictly increasing.
Matrix sensor_description_amsu(Workspace &ws) noexcept
Index nrows() const
Returns the number of rows.
Vector stokes_rotation(Workspace &ws) noexcept
void sensor_aux_vectors(Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, ConstVectorView sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, ConstMatrixView sensor_response_dlos_grid)
sensor_aux_vectors
bool is_multiple(const Index &x, const Index &y)
Checks if an integer is a multiple of another integer.
void sensor_responsePolarisation(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, ArrayOfIndex &sensor_response_pol_grid, const Vector &sensor_response_f_grid, const Matrix &sensor_response_dlos_grid, const Index &stokes_dim, const String &iy_unit, const ArrayOfIndex &instrument_pol, const Verbosity &)
WORKSPACE METHOD: sensor_responsePolarisation.
void sensor_responseWMRF(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Sparse &wmrf_weights, const Vector &f_backend, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseWMRF.
void stokes2pol(VectorView w, const Index &stokes_dim, const Index &ipol_1based, const Numeric nv)
stokes2pol
ArrayOfIndex wmrf_channels(Workspace &ws) noexcept
void VectorNLogSpace(Vector &x, const Index &n, const Numeric &start, const Numeric &stop, const Verbosity &verbosity)
WORKSPACE METHOD: VectorNLogSpace.
Header file for special_interp.cc.
void resize(const GriddedField1 &gf)
Make this GriddedField1 the same size as the given one.
ArrayOfGriddedField1 sideband_response_multi(Workspace &ws) noexcept
Helper comparison class to sort an array or vector based on an ArrayOfNumeric.
void sensor_responseBeamSwitching(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Matrix &sensor_response_dlos_grid, const Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Numeric &w1, const Numeric &w2, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseBeamSwitching.
Matrix jacobian(Workspace &ws) noexcept
Vector x(Workspace &ws) noexcept
void sensor_responseStokesRotation(Sparse &sensor_response, const Vector &sensor_response_f_grid, const ArrayOfIndex &sensor_response_pol_grid, const Matrix &sensor_response_dlos_grid, const Index &stokes_dim, const Vector &stokes_rotation, const Verbosity &)
WORKSPACE METHOD: sensor_responseStokesRotation.
INDEX Index
The type to use for all integer numbers and indices.
std::vector< T > linspace(T s, T e, typename std::vector< T >::size_type count) noexcept
Matrix sensor_response_dlos(Workspace &ws) noexcept
ConstComplexMatrixView transpose(ConstComplexMatrixView m)
Const version of transpose.
void Select(Array< T > &needles, const Array< T > &haystack, const ArrayOfIndex &needleind, const Verbosity &)
void yApplySensorPol(Vector &y, Vector &y_f, ArrayOfIndex &y_pol, Matrix &y_pos, Matrix &y_los, ArrayOfVector &y_aux, Matrix &y_geo, Matrix &jacobian, const Index &stokes_dim, const Index &jacobian_do, const Matrix &sensor_pos, const Matrix &sensor_pol, const Verbosity &)
WORKSPACE METHOD: yApplySensorPol.
void gridpos_poly(ArrayOfGridPosPoly &gp, ConstVectorView old_grid, ConstVectorView new_grid, const Index order, const Numeric &extpolfac)
The maximum difference from 1 that we allow for a sum check.
Index ncols(Workspace &ws) noexcept
ArrayOfString sideband_mode_multi(Workspace &ws) noexcept
void sensor_responseMetMM(Index &antenna_dim, Matrix &mblock_dlos_grid, Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, ArrayOfIndex &sensor_response_pol_grid, Matrix &sensor_response_dlos_grid, Index &sensor_norm, const Index &atmosphere_dim, const Index &stokes_dim, const Vector &f_grid, const Vector &f_backend, const ArrayOfArrayOfIndex &channel2fgrid_indexes, const ArrayOfVector &channel2fgrid_weights, const String &iy_unit, const Matrix &antenna_dlos, const ArrayOfString &mm_pol, const Vector &mm_ant, const Index &use_antenna, const Index &mirror_dza, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseMetMM.
A constant view of a Vector.
void f_gridFromSensorHIRS(Vector &f_grid, const Vector &f_backend, const ArrayOfGriddedField1 &backend_channel_response, const Numeric &spacing, const Verbosity &verbosity)
WORKSPACE METHOD: f_gridFromSensorHIRS.
Contains sorting routines.
Index nelem() const
Number of elements.
void sensor_responseInit(Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, ArrayOfIndex &sensor_response_pol_grid, Matrix &sensor_response_dlos_grid, const Vector &f_grid, const Matrix &mblock_dlos_grid, const Index &antenna_dim, const Index &atmosphere_dim, const Index &stokes_dim, const Index &sensor_norm, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseInit.
Matrix sensor_los(Workspace &ws) noexcept
Matrix y_geo(Workspace &ws) noexcept
const Index GFIELD4_F_GRID
void interpweights(VectorView itw, const GridPos &tc)
Red 1D interpolation weights.
String sideband_mode(Workspace &ws) noexcept
The global header file for ARTS.
void mueller_rotation(Sparse &H, const Index &stokes_dim, const Numeric &rotangle)
mueller_rotation
void sensor_responseGenericAMSU(Vector &f_grid, Index &antenna_dim, Matrix &mblock_dlos_grid, Sparse &sensor_response, Vector &sensor_response_f, ArrayOfIndex &sensor_response_pol, Matrix &sensor_response_dlos, Vector &sensor_response_f_grid, ArrayOfIndex &sensor_response_pol_grid, Matrix &sensor_response_dlos_grid, Index &sensor_norm, const Index &atmosphere_dim, const Index &stokes_dim, const Matrix &sensor_description_amsu, const Numeric &spacing, const Verbosity &verbosity)
WORKSPACE METHOD: sensor_responseGenericAMSU.
This file contains basic functions to handle XML data files.
void f_gridMetMM(Vector &f_grid, Vector &f_backend, ArrayOfArrayOfIndex &channel2fgrid_indexes, ArrayOfVector &channel2fgrid_weights, const Matrix &mm_back, const Vector &freq_spacing, const ArrayOfIndex &freq_number, const Numeric &freq_merge_threshold, const Verbosity &)
WORKSPACE METHOD: f_gridMetMM.
void WMRFSelectChannels(Vector &f_grid, Sparse &wmrf_weights, Vector &f_backend, const ArrayOfIndex &wmrf_channels, const Verbosity &verbosity)
WORKSPACE METHOD: WMRFSelectChannels.
Index sensor_norm(Workspace &ws) noexcept