74 #include <uves_physmod_utils.h>
76 #include <uves_utils.h>
77 #include <uves_utils_wrappers.h>
78 #include <uves_error.h>
90 beta2lamb(
double uves_beta_ech,
double uves_beta_cd,
double* plambda,
int m);
93 cameraFocal(
double lm);
96 uves_physmod_find_alpha_beta(
double lm,
104 uves_physmod_find_lambda(
double k,
double alpha,
double beta);
107 uves_physmod_find_order_lambda(
double k,
double alpha,
double beta);
117 uves_physmod_lambda_order_beta(
double* plambda,
121 double* puves_beta_ech,
122 double* puves_beta_cd);
125 uves_physmod_lambda_order_focus_model(
double* plambda,
131 static double uves_physmod_wave_bin(
double l,
int m);
133 static void uves_physmod_xy2beta(
double* puves_beta_ech,
134 double* puves_beta_cd,
139 static void uves_physmod_set_binning(
float binx,
float biny);
141 static double dsqrarg;
147 #define DSQR(a) ((dsqrarg=(a)) == 0.0 ? 0.0 : dsqrarg*dsqrarg)
149 #define PROID "physmod.c"
154 enum uves_arm_ident {UVES_ARM_UNDEF,UVES_ARM_BLUE,UVES_ARM_RED};
155 enum uves_arm_ident uves_arm_ident = UVES_ARM_UNDEF;
163 float uves_bin[2] = {1, 1};
164 static double uves_physmod_pix_size[2] = {15e-6, 15e-6};
165 static double delta[2] = {75.04, 76.0};
167 static double cdgroov[4] = {1000.0e-6, 660.0e-6, 600.0e-6, 312.5e-6};
168 static double uves_ech_groov[2] = {31.6e-6, 41.59e-6};
171 static double uves_ech_blaze[2] = {74.57, 75.9};
175 static double cdbeam[2] = {45.336, 46.0};
179 double uves_ccd_rot[2] = {0.3, -0.55};
182 static int imsize[2] = {4096, 3000};
183 static int uves_physmod_row_size[2] = {2048, 2048};
192 double uves_physmod_offsetx[6]={1391.0,1385.0,1852.0,1835.0,1852.0,1834.0};
193 double uves_physmod_offsety[6]={1030.0,1025.0,2098.0,2104.0,-52.0,-49.0};
199 static double flipx = 1.;
200 static double flipy = -1.;
201 double uves_airt = 25;
202 double uves_airp = 760;
203 double uves_airw = 3;
205 int uves_cfg_indx = 0;
206 int uves_x_disp_id = 0;
207 static int uves_ech_id = 0;
208 double uves_alpha0_cd, uves_beta0_cd;
209 char uves_arm_id =
'x';
211 static double uves_deg2rad = M_PI/180.;
260 uves_physmod_set_incidence(
double echred,
265 uves_ech_blaze[0] += echred;
266 uves_ech_blaze[1] += echblue;
270 uves_ech_blaze[0],uves_ech_blaze[1],cdbeam[0],cdbeam[1]);
280 uves_set_ccd_rot(
double* ccdrot,
281 double uves_ccd_rot_off_red,
282 double uves_ccd_rot_off_blue)
284 uves_ccd_rot[0] =ccdrot[0];
285 uves_ccd_rot[1] =ccdrot[1];
287 uves_ccd_rot[0] += uves_ccd_rot_off_red;
288 uves_ccd_rot[1] += uves_ccd_rot_off_blue;
290 uves_msg_debug(
"uves_ccd_rot[0,1]=%f,%f uves_ccd_rot_off: red,blue=%f,%f",
291 uves_ccd_rot[0],uves_ccd_rot[1],uves_ccd_rot_off_red,uves_ccd_rot_off_blue);
305 uves_physmod_set_offset(
double offset_x,
307 double uves_physmod_x_off,
310 uves_physmod_offsetx[uves_cfg_indx-1]=offset_x;
311 uves_physmod_offsety[uves_cfg_indx-1]=offset_y;
323 uves_physmod_offsetx[uves_cfg_indx-1] += uves_physmod_x_off;
324 uves_physmod_offsety[uves_cfg_indx-1] += yoff;
344 void uves_physmod_set_binning(
float binx,
float biny)
361 void uves_air_config(
double p,
double t,
double w)
367 uves_airt,uves_airp,uves_airw);
374 double uves_air_index(
double lambda)
377 double t1, t2, t3, airdx;
379 t1 = 1.0e-6/lambda/lambda;
381 t2 = (64.328+29498.1/(146.0-t1)+255.4/(41.0-t1))*uves_airp*
382 (1.0+1.0e-6*(1.049-0.0157*uves_airt)*uves_airp)/
383 (720.883*(1.0+0.003661*uves_airt));
385 t3 = t2 - uves_airw*(0.0624 - 0.000680*t1)/(1+0.003661*uves_airt);
387 airdx = 1.0+ t3*1.0e-6;
409 uves_physmod_find_alpha_beta(
double lm,
420 lm /= uves_air_index(lm);
422 *alpha = 0.5* ( 2*asin( m*k*lm/2/cos(theta*uves_deg2rad/2) ) +
423 theta*uves_deg2rad );
424 *beta = 0.5* ( 2*asin( m*k*lm/2/cos(theta*uves_deg2rad/2) ) -
425 theta*uves_deg2rad );
426 *alpha /= uves_deg2rad;
427 *beta /= uves_deg2rad;
446 uves_config(
char uves_arm,
456 uves_x_disp_id = disp;
457 uves_arm_id = uves_arm;
469 uves_msg(
"Cfg: Arm %c CCD %c Xdisp %d Wave %f",
470 uves_arm,uves_ccd_id,disp,waveCent);
472 if (uves_arm ==
'b' && disp == 1) cfg = 1;
473 if (uves_arm ==
'b' && disp == 2) cfg = 2;
475 if (uves_arm ==
'r' && disp == 3) {
477 if (uves_ccd_id ==
'e') cfg = 3;
478 if (uves_ccd_id ==
'm') cfg = 5;
480 if (uves_arm ==
'r' && disp == 4) {
482 if (uves_ccd_id ==
'e') cfg = 4;
483 if (uves_ccd_id ==
'm') cfg = 6;
487 cpl_msg_error(__func__,
"Wrong configuration!");
493 (void) uves_physmod_set_binning(binx, biny);
494 (void) uves_physmod_find_alpha_beta(waveCent, 1, cdgroov[uves_x_disp_id-1],
495 cdbeam[uves_ech_id-1], &uves_alpha0_cd, &uves_beta0_cd);
498 uves_msg(
"alpha, beta for Xdisp: %f %f\nin config %d and CCD-ID %c",
499 uves_alpha0_cd, uves_beta0_cd,cfg, uves_ccd_id);
514 uves_config_cpl_new(
int uves_arm,
523 uves_x_disp_id = disp;
535 uves_msg(
"New Cfg: Arm [b/r] %d CCD eev/mit %d Xdisp %d Wave %f",
536 uves_arm,upper,disp,waveCent);
538 if (uves_arm == ARM_BLUE && disp == 1) cfg = 1;
539 if (uves_arm == ARM_BLUE && disp == 2) cfg = 2;
541 if (uves_arm == ARM_RED && disp == 3) {
543 if (upper == 0) cfg = 3;
544 if (upper == 1) cfg = 5;
546 if (uves_arm == ARM_RED && disp == 4) {
548 if (upper == 0) cfg = 4;
549 if (upper == 1) cfg = 6;
553 cpl_msg_error(__func__,
"Wrong configuration!");
559 (void) uves_physmod_set_binning(binx, biny);
560 (void) uves_physmod_find_alpha_beta(waveCent, 1, cdgroov[uves_x_disp_id-1],
561 cdbeam[uves_ech_id-1], &uves_alpha0_cd, &uves_beta0_cd);
564 uves_msg(
"alpha, beta for Xdisp: %f %f\nin config %d and CCD-ID %c",
565 uves_alpha0_cd, uves_beta0_cd,cfg, upper == 0 ?
'e' :
'm');
590 uves_config_cpl(
int blue,
601 uves_x_disp_id = disp;
613 uves_msg(
"Cfg cpl: Arm [b/r] %d CCD eev/mit %d Xdisp %d Wave %f",
614 blue,upper,disp,waveCent);
616 if (blue == 1 && disp == 1) cfg = 1;
617 if (blue == 1 && disp == 2) cfg = 2;
619 if (blue == 0 && disp == 3) {
621 if (upper == 0) cfg = 3;
622 if (upper == 1) cfg = 5;
624 if (blue == 0 && disp == 4) {
626 if (upper == 0) cfg = 4;
627 if (upper == 1) cfg = 6;
637 (void) uves_physmod_set_binning(binx, biny);
638 (void) uves_physmod_find_alpha_beta(waveCent, 1, cdgroov[uves_x_disp_id-1],
639 cdbeam[uves_ech_id-1], &uves_alpha0_cd, &uves_beta0_cd);
642 uves_msg(
"alpha, beta for Xdisp: %f %f\nin config %d and CCD-ID %c",
643 uves_alpha0_cd, uves_beta0_cd,cfg, upper == 0 ?
'e':
'u');
668 double cameraFocal(
double lm)
675 lm /= uves_air_index(lm);
677 if (uves_arm_id ==
'b' ) {
679 nfk=5.3961886e-7*lm*lm*lm-0.00079597882*lm*lm+0.41122805*lm+287.89644;
682 if (uves_arm_id ==
'r' ) {
684 nfk=6.0172051e-13*lm*lm*lm*lm*lm-2.5623231e-9*lm*lm*lm*lm+
685 4.3585543e-6*lm*lm*lm -0.0037286381*lm*lm+
686 1.6289971*lm + 210.06767;
702 int uves_physmod_find_order(
double lm)
705 double k, alpha, beta;
707 lm /= uves_air_index(lm);
709 k = uves_ech_groov[uves_ech_id-1];
710 alpha = uves_ech_blaze[uves_ech_id-1];
711 beta = uves_ech_blaze[uves_ech_id-1];
712 order = (int)((sin(alpha*uves_deg2rad) + sin(beta*uves_deg2rad))/k/lm + 0.5);
727 double uves_physmod_find_order_lambda(
double k,
double alpha,
double beta)
730 ML = ( ( sin(alpha*uves_deg2rad) + sin(beta*uves_deg2rad) )/k);
731 ML *= uves_air_index(ML);
742 double uves_physmod_find_lambda(
double k,
double alpha,
double beta)
745 L = (sin(alpha*uves_deg2rad) + sin(beta*uves_deg2rad) )/k ;
746 L *= uves_air_index(L);
757 double uves_physmod_find_beta(
int m,
double k,
double l,
double alpha)
761 l /= uves_air_index(l);
770 if ( (m*k*l - sin(alpha*uves_deg2rad)) <=1.0 )
772 return( (asin(m*k*l - sin(alpha*uves_deg2rad)))/uves_deg2rad );
776 return( (asin(0.999))/uves_deg2rad );
789 uves_physmod_lambda_order2beta(
double lambda,
791 double* puves_beta_ech,
792 double* puves_beta_cd,
799 *pfc = cameraFocal(lambda);
803 *puves_beta_ech = uves_physmod_find_beta(m, uves_ech_groov[uves_ech_id-1],
804 lambda, uves_ech_blaze[uves_ech_id-1]);
806 *puves_beta_cd = uves_physmod_find_beta(1, cdgroov[uves_x_disp_id-1],
807 lambda, uves_alpha0_cd);
822 uves_beta2xy(
double uves_beta_cd,
823 double uves_beta_ech,
828 double xd, yd, xr, yr, angle;
830 xd = fc*tan( (uves_beta_ech - uves_ech_blaze[uves_ech_id-1])*
832 uves_physmod_pix_size[0]/uves_bin[0];
833 yd = fc*tan( (uves_alpha0_cd - uves_beta_cd -
834 cdbeam[uves_ech_id-1])*uves_deg2rad )/
835 uves_physmod_pix_size[1]/uves_bin[1];
844 angle = uves_ccd_rot[uves_ech_id-1]*uves_deg2rad;
845 xr = xd*cos(angle) + yd*sin(angle);
846 yr = -xd*sin(angle) + yd*cos(angle);
850 *px = uves_physmod_offsetx[uves_cfg_indx-1] / uves_bin[0] + xr;
851 *py = uves_physmod_offsety[uves_cfg_indx-1] / uves_bin[1] + yr;
867 uves_physmod_photo_beta(
double lambda,
868 double uves_beta_ech,
870 double* puves_physmod_rech,
871 double* puves_physmod_rcd,
881 *puves_physmod_rech = cos(uves_ech_blaze[uves_ech_id-1]*uves_deg2rad)/
882 cos(uves_beta_ech*uves_deg2rad);
884 *puves_physmod_rcd = cos(uves_alpha0_cd*uves_deg2rad)/
885 cos(uves_beta_cd*uves_deg2rad);
891 gam = M_PI / uves_ech_groov[uves_ech_id-1] *
892 cos(delta[uves_ech_id-1]*uves_deg2rad) *
893 (sin((uves_beta_ech-delta[uves_ech_id-1])*uves_deg2rad)-
894 sin((uves_ech_blaze[uves_ech_id-1]-delta[uves_ech_id-1])*
896 / lambda/ uves_air_index(lambda);
897 *pblz = DSQR(sin(gam)/gam);
926 void uves_physmod_pixscl(
929 double uves_physmod_rech,
930 double uves_physmod_rcd,
944 double binsize, pixscale, pixscalCD, linewidpx, linelenpx, linewidth, resol;
947 if (!(scale)) scale = (206265.0*15.0*0.015*200*1e-3*binx)/120000;
968 binsize = uves_physmod_wave_bin(wave, order) * 1e4;
969 pixscale = scale/(fc*uves_physmod_rech);
970 pixscalCD = pixscale *(biny/binx) *uves_physmod_rech/uves_physmod_rcd;
971 linewidpx = slitwidth / pixscale;
972 linelenpx = slitlength /pixscalCD;
973 linewidth = binsize * linewidpx * 1e-3;
974 resol = wave * 10.0 / linewidth;
985 *ppixscale = pixscale;
986 *ppixscalCD = pixscalCD;
987 *plinewidpx = linewidpx;
988 *plinelenpx = linelenpx;
989 *plinewidth = linewidth;
1002 uves_physmod_xy_model(
double lambda,
int m,
double* px,
double* py)
1004 double fc, uves_beta_ech, uves_beta_cd;
1006 uves_physmod_lambda_order2beta(lambda, m, &uves_beta_ech, &uves_beta_cd, &fc);
1007 uves_msg_debug(
"lambda=%f m=%d uves_beta_ech=%f,uves_beta_cd=%f,fc=%f",
1008 lambda,m,uves_beta_ech,uves_beta_cd,fc);
1010 uves_beta2xy(uves_beta_cd, uves_beta_ech, fc, px, py);
1029 uves_physmod_xy2beta(
double* puves_beta_ech,
1030 double* puves_beta_cd,
1035 double xr, yr, xd, yd, angle;
1037 angle = uves_ccd_rot[uves_ech_id-1]*uves_deg2rad;
1039 xr = (x - uves_physmod_offsetx[uves_cfg_indx-1]/uves_bin[0]);
1040 yr = (y - uves_physmod_offsety[uves_cfg_indx-1]/uves_bin[1]);
1042 xd = xr*cos(angle) - yr*sin(angle);
1043 yd = xr*sin(angle) + yr*cos(angle);
1048 *puves_beta_ech = atan(xd*uves_physmod_pix_size[0]*uves_bin[0]/fc)/
1049 uves_deg2rad + uves_ech_blaze[uves_ech_id-1];
1050 *puves_beta_cd = uves_alpha0_cd - cdbeam[uves_ech_id-1] -
1051 atan(yd*uves_physmod_pix_size[1]*uves_bin[1]/fc)/
1065 beta2lamb(
double uves_beta_ech,
1066 double uves_beta_cd,
1070 uves_beta_cd=uves_beta_cd;
1071 *plambda = uves_physmod_find_lambda(m*uves_ech_groov[uves_ech_id-1],
1072 uves_ech_blaze[uves_ech_id-1], uves_beta_ech);
1089 uves_physmod_lambda_order_focus_model(
double* plambda,
1096 double uves_beta_ech, uves_beta_cd;
1098 uves_physmod_xy2beta(&uves_beta_ech, &uves_beta_cd, fc, x, y);
1100 *plambda = uves_physmod_find_order_lambda(cdgroov[uves_x_disp_id-1],
1101 uves_alpha0_cd, uves_beta_cd);
1102 *pdm = uves_physmod_find_order_lambda(uves_ech_groov[uves_ech_id-1],
1103 uves_ech_blaze[uves_ech_id-1], uves_beta_ech)/(*plambda);
1149 uves_physmod_lambda_order_beta(
double* plambda,
1153 double* puves_beta_ech,
1154 double* puves_beta_cd)
1157 double fcguess=0., wave=0., mdbl=0., xe=0., ye=0., xd=0., yd=0.;
1160 if (uves_arm_id ==
'b') fcguess = 0.360;
1161 if (uves_arm_id ==
'r') fcguess = 0.500;
1163 uves_physmod_lambda_order_focus_model(&wave,&mdbl,fcguess,x,y);
1172 fcguess = cameraFocal(wave);
1178 if (*pm <= 0) *pm = (int)(mdbl+0.5);
1180 uves_physmod_xy2beta(puves_beta_ech, puves_beta_cd, fcguess, x, y);
1181 beta2lamb(*puves_beta_ech, *puves_beta_cd, &wave, *pm);
1189 uves_physmod_xy_model(wave,(
int)(mdbl+0.5), &xe, &ye);
1202 }
while (!((xd < 1.) && (yd < 1.)) && (i <= 4));
1229 uves_physmod_lambda_order_model(
double* plambda,
int* pm,
double x,
double y)
1232 double uves_beta_ech, uves_beta_cd;
1234 uves_physmod_lambda_order_beta(plambda, pm, x, y,
1235 &uves_beta_ech, &uves_beta_cd);
1255 uves_physmod_find_FSR(
int m,
double* lambdaC,
double* fsrStart,
double* fsrEnd)
1260 *lambdaC = 2*sin(uves_ech_blaze[uves_ech_id-1]*uves_deg2rad)/
1261 m/uves_ech_groov[uves_ech_id-1];
1263 tmp_delta = *lambdaC/m;
1265 *fsrStart = *lambdaC - tmp_delta/2.;
1266 *fsrEnd = *lambdaC + tmp_delta/2.;
1275 double uves_physmod_wave_bin(
double l,
int m)
1278 double dl, x0,y_0,x1,y_1;
1282 uves_physmod_xy_model( l, m,&x0,&y_0);
1283 uves_physmod_xy_model((l+dl),m,&x1,&y_1);
1285 return( dl/(x1-x0) );
1293 void uves_ccd_size(
int* nx,
int* ny)
1304 *nx = imsize[uves_ech_id-1] / uves_bin[0];
1305 *ny = uves_physmod_row_size[uves_ech_id-1] / uves_bin[1];
1318 void uves_physmod_xy_regres(
double x,
double y,
double* px,
double* py)
1351 uves_ccd_size(&xnpix, &ynpix);
1353 xdiff = (-7.)*(x-(double)xnpix/2.)/((double)xnpix/2.);
1355 ydiff = (5.)*DSQR((x-(
double)xnpix/2.)/((
double)xnpix/2.));
#define uves_msg_error(...)
Print an error message.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
#define uves_msg_debug(...)
Print a debug message.