Gateau User Manual
Atmospheric simulation of astronomical signals
utilities.h
Go to the documentation of this file.
1 /*! \file utilities.h
2  * \brief Utilities for linear interpolation for CUDA.
3  **/
4 #include <stdexcept>
5 
6 #include "cuda.h"
7 #include "math.h"
8 #include "structs.h"
9 
10 #include <gsl/gsl_fit.h>
11 
12 #define NPWV 1000
13 #define PWV_START 0.1
14 #define PWV_END 5.5
15 #define DPWV 0.0054
16 
17 #ifndef __UTILITIES_H
18 #define __UTILITIES_H
19 
20 /**
21  Linearly interpolate bivariate function.
22 
23  @param x Point in x to interpolate on.
24  @param y Point in y to interpolate on.
25  @param x0 Start of x-coordinates.
26  @param y0 Start of y-coordinates.
27  @param size_x Size of array containing x-coordinates.
28  @param size_y Size of array containing y-coordinates.
29  @param dx Stepsize of x.
30  @param dy Stepsize of y.
31  @param vals Function values on grid spanning x and y.
32  @param size_vals Size of array containing values.
33 
34  @returns val_interp Interpolated value of function on x0 and y0.
35  */
36 __host__ __device__
38  float x,
39  float y,
40  ArrSpec *arrx,
41  ArrSpec *arry,
42  float *vals,
43  int offset,
44  float &out
45  )
46 {
47  int idx_x = floorf((x - arrx->start) / arrx->step);
48  int idx_y = floorf((y - arry->start) / arry->step);
49 
50  float t = (x - (arrx->start + arrx->step*idx_x)) / arrx->step;
51  float u = (y - (arry->start + arry->step*idx_y)) / arry->step;
52 
53  out = (1-t)*(1-u) * vals[idx_x * arry->num + idx_y + offset];
54  out += t*(1-u) * vals[(idx_x + 1) * arry->num + idx_y + offset];
55  out += (1-t)*u * vals[idx_x * arry->num + idx_y + 1 + offset];
56  out += t*u * vals[(idx_x + 1) * arry->num + idx_y + 1 + offset];
57 }
58 
59 /**
60  Cascade a PSD through a reflector system, and couple to a specific parasitic PSD.
61 
62  @param P_nu_in PSD of incoming signal to be cascaded.
63  @param eta Efficiency term associated with cascade.
64  @param T_parasitic Temperature of parasitic source.
65  @param nu Frequency in Hz.
66 
67  @returns Cascade output PSD.
68  */
69 __host__ __device__
70 float rad_trans(
71  float psd_in,
72  float eta,
73  float psd_parasitic
74  )
75 {
76  return eta * psd_in + (1 - eta) * psd_parasitic;
77 }
78 
79 __host__
80 void resp_calibration(
81  int start,
82  int stop,
83  ArrSpec *f_atm,
84  ArrSpec *pwv_atm,
85  ArrSpec *f_src,
86  float Tp_atm,
87  int nf_ch,
88  float *eta_cascade,
89  float *psd_cascade,
90  float *psd_cmb,
91  int num_stage,
92  float *psd_atm,
93  float *eta_atm,
94  float *filterbank,
95  float *eta_kj_sum,
96  float *Psky,
97  float *Tsky
98  )
99 {
100  // FLOATS
101  float eta_atm_interp; // Interpolated eta_atm, over frequency and PWV
102  float freq; // Bin frequency
103  float psd_in; // Local variable for storing PSD.
104  float psd_in_k; // Local variable for calculating psd per channel
105  float eta_kj; // Filter efficiency for bin j, at channel k.
106  float psd_parasitic_use;
107  float psd_cmb_loc;
108  float psd_sky;
109  float pwv_loc;
110  float psd_atm_loc;
111  float temp1, temp2;
112 
113  float *eta_atm_smooth = new float[nf_ch]();
114 
115  for(int idx=start; idx<stop; idx++)
116  {
117  pwv_loc = PWV_START + idx*DPWV;
118  for(int idy=0; idy<f_src->num; idy++)
119  {
120  freq = f_src->start + f_src->step * idy;
121 
122  interpValue(
123  pwv_loc,
124  freq,
125  pwv_atm,
126  f_atm,
127  eta_atm,
128  0,
129  eta_atm_interp
130  );
131 
132  psd_atm_loc = psd_atm[idy];
133  psd_cmb_loc = psd_cmb[idy];
134 
135  // Initial pass through atmosphere
136  psd_sky = rad_trans(
137  psd_cmb_loc,
138  eta_atm_interp,
139  psd_atm_loc
140  );
141 
142  psd_in = psd_sky;
143 
144  // Radiative transfer cascade
145  for (int n=0; n<num_stage; n++)
146  {
147  psd_parasitic_use = psd_cascade[n*f_src->num + idy];
148  if (psd_parasitic_use < 0)
149  {
150  psd_parasitic_use = psd_sky;
151  }
152 
153  psd_in = rad_trans(
154  psd_in,
155  eta_cascade[n*f_src->num + idy],
156  psd_parasitic_use
157  );
158  }
159 
160  for(int k=0; k<nf_ch; k++)
161  {
162  eta_kj = filterbank[k*f_src->num + idy];
163 
164  psd_in_k = psd_in * eta_kj;
165 
166  Psky[k*NPWV + idx] += psd_in_k * f_src->step;
167  eta_atm_smooth[k] += eta_kj * eta_atm_interp;
168  }
169  }
170 
171  for(int k=0; k<nf_ch; k++)
172  {
173  Tsky[k*NPWV + idx] += (1 - eta_atm_smooth[k] / eta_kj_sum[k]) * Tp_atm;
174  eta_atm_smooth[k] = 0.;
175  }
176  }
177  delete[] eta_atm_smooth;
178 }
179 
180 __host__
181 void fit_calibration(
182  float *Psky,
183  float *Tsky,
184  int nf_ch,
185  float *c0,
186  float *c1
187  )
188 {
189  double c0_loc, c1_loc, cov00, cov01, cov11, sumsq;
190 
191  double *Psky_k = new double[NPWV];
192  double *Tsky_k = new double[NPWV];
193 
194  for(int k=0; k<nf_ch; k++)
195  {
196  for(int j=0; j<NPWV; j++)
197  {
198  Psky_k[j] = static_cast<double>(Psky[k*NPWV + j]);
199  Tsky_k[j] = static_cast<double>(Tsky[k*NPWV + j]);
200  }
201  gsl_fit_linear(
202  Psky_k,
203  1,
204  Tsky_k,
205  1,
206  NPWV,
207  &c0_loc,
208  &c1_loc,
209  &cov00,
210  &cov01,
211  &cov11,
212  &sumsq
213  );
214 
215  c0[k] = static_cast<float>(c0_loc);
216  c1[k] = static_cast<float>(c1_loc);
217  }
218  delete[] Psky_k;
219  delete[] Tsky_k;
220 }
221 
222 #endif
interpValue
__host__ __device__ void interpValue(float x, float y, ArrSpec *arrx, ArrSpec *arry, float *vals, int offset, float &out)
Definition: utilities.h:37
ArrSpec
Definition: structs.h:16
structs.h
Data structures for receiving data from Python interface.
rad_trans
__host__ __device__ float rad_trans(float psd_in, float eta, float psd_parasitic)
Definition: utilities.h:70