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