29#include "vircam_channel.h"
30#include "vircam_utils.h"
31#include <casu_utils.h>
36#define NCHANTAB_COLS 15
37static const char *chantab_columns[] = {
"channum",
53static const cpl_type chantab_types[] = {CPL_TYPE_INT,
68#define NTESTPOSITIVE 7
69static const char *testpositive[] = {
"channum",
78static const char *test1[] = {
"dcd1_1",
85static int vircam_chan_init(
int channum,
int ixmin,
int ixmax,
int iymin,
86 int iymax,
int dcrpix1,
int dcrpix2,
int dcd1_1,
87 int dcd1_2,
int dcd2_1,
int dcd2_2, parquet *p);
88static void vircam_chan_close(parquet *p);
89static int vircam_chan_testpos(cpl_table *intab,
const char *column);
90static int vircam_chan_test1(cpl_table *intab,
const char *column);
91static int vircam_chan_fill_lin(cpl_table *intab,
int row, parquet *p);
133 int i,missing[NCHANTAB_COLS],wrongtype[NCHANTAB_COLS],ierr,norder;
136 const char *fctid =
"vircam_chantab_verify";
137 char errmsg[1024],colname[SZCOL],msg[1024];
145 cpl_msg_error(fctid,
"Null input channel table");
153 for (i = 0; i < NCHANTAB_COLS; i++) {
156 if (cpl_table_has_column(intab,chantab_columns[i]) != 1) {
159 }
else if (cpl_table_get_column_type(intab,chantab_columns[i]) !=
166 (void)strcat(errmsg,
"These columns are missing or have incorrect types");
167 for (i = 0; i < NCHANTAB_COLS; i++) {
168 if (missing[i] == 1) {
169 (void)strcat(errmsg,
"\n");
170 (void)strcat(errmsg,chantab_columns[i]);
171 (void)strcat(errmsg,
" Missing");
172 }
else if (wrongtype[i] == 1) {
173 (void)strcat(errmsg,
"\n");
174 (void)strcat(errmsg,chantab_columns[i]);
175 (void)strcat(errmsg,
" Wrong type");
178 (void)strcat(errmsg,
"\n");
185 cols = cpl_table_get_column_names(intab);
186 ig = (int)cpl_array_get_size(cols);
187 for (i = 0; i < ig; i++) {
188 col = cpl_array_get_string(cols,(cpl_size)i);
189 if (! strncmp(col,
"coeff_",6)) {
190 if (cpl_table_get_column_type(intab,col) != CPL_TYPE_DOUBLE) {
191 (void)sprintf(msg,
"Column %s must be double\n",col);
192 (void)strcat(errmsg,msg);
196 cpl_array_delete(cols);
202 for (i = 0; i < NTESTPOSITIVE; i++) {
204 if (vircam_chan_testpos(intab,testpositive[i]) == CASU_OK)
210 (void)strcat(errmsg,
"These columns should be positive integers only:");
211 for (i = 0; i < NTESTPOSITIVE; i++) {
212 if (missing[i] == 1) {
213 (void)strcat(errmsg,
"\n");
214 (void)strcat(errmsg,testpositive[i]);
217 (void)strcat(errmsg,
"\n");
223 for (i = 0; i < NTEST1; i++) {
225 if (vircam_chan_test1(intab,test1[i]) == CASU_OK)
231 (void)strcat(errmsg,
"These columns should be integers and (-1,0,1) only:");
232 for (i = 0; i < NTEST1; i++) {
233 if (missing[i] == 1) {
234 (void)strcat(errmsg,
"\n");
235 (void)strcat(errmsg,test1[i]);
238 (void)strcat(errmsg,
"\n");
245 norder = cpl_table_get_int(intab,
"norder",0,&null);
246 nrows = (int)cpl_table_get_nrow(intab);
247 c1 = cpl_table_get_data_double(intab,
"coeff_1");
248 for (i = 0; i < nrows; i++) {
250 (void)strcat(errmsg,
"\ncoeff_1 must be all 1s!\n");
254 for (i = 2; i <= norder; i++) {
256 (void)snprintf(colname,SZCOL,
"coeff_%d",i);
257 if (cpl_table_has_column(intab,colname) != 1) {
264 "\nThese coefficient columns are missing from the channel table:");
265 for (i = 2; i < norder; i++) {
266 if (missing[i] == 1) {
267 (void)snprintf(colname,SZCOL,
"coeff_%d",i);
268 (void)strcat(errmsg,
"\n");
269 (void)strcat(errmsg,colname);
272 (void)strcat(errmsg,
"\n");
277 if (errmsg[0] !=
'\0') {
278 cpl_msg_error(fctid,
"Errors in channel table\n%s",errmsg);
311 int i,oldnorder,j,nr,null;
316 tab = cpl_table_duplicate(
template);
321 oldnorder = cpl_table_get_int(tab,
"norder",0,&null);
322 if (oldnorder > nord) {
323 for (i = nord+1; i <= oldnorder; i++) {
324 (void)snprintf(colname,SZCOL,
"coeff_%d",i);
325 cpl_table_erase_column(tab,colname);
327 }
else if (oldnorder < nord) {
328 for (i = oldnorder+1; i <= nord; i++) {
329 (void)snprintf(colname,SZCOL,
"coeff_%d",i);
330 if (cpl_table_has_column(tab,colname))
332 cpl_table_new_column(tab,colname,CPL_TYPE_DOUBLE);
338 nr = (int)cpl_table_get_nrow(tab);
339 for (i = 0; i < nr; i++) {
340 cpl_table_set_int(tab,
"norder",(cpl_size)i,nord);
341 cpl_table_set_double(tab,
"coeff_1",(cpl_size)i,1.0);
342 for (j = 2; j <= nord; j++) {
343 char * colname1 = cpl_sprintf(
"coeff_%d",j);
345 cpl_table_set_double(tab,colname1,(cpl_size)i,0.0);
386 int i,channum,ixmin,ixmax,iymin,iymax,null;
387 int dcrpix1,dcrpix2,dcd1_1,dcd1_2,dcd2_1,dcd2_2,retval;
397 *np = (int)cpl_table_get_nrow(tab);
398 *p = cpl_malloc(*np*
sizeof(parquet));
402 for (i = 0; i < *np; i++) {
404 channum = cpl_table_get_int(tab,
"channum",(cpl_size)i,&null);
405 ixmin = cpl_table_get_int(tab,
"ixmin",(cpl_size)i,&null);
406 ixmax = cpl_table_get_int(tab,
"ixmax",(cpl_size)i,&null);
407 iymin = cpl_table_get_int(tab,
"iymin",(cpl_size)i,&null);
408 iymax = cpl_table_get_int(tab,
"iymax",(cpl_size)i,&null);
409 dcrpix1 = cpl_table_get_int(tab,
"dcrpix1",(cpl_size)i,&null);
410 dcrpix2 = cpl_table_get_int(tab,
"dcrpix2",(cpl_size)i,&null);
411 dcd1_1 = cpl_table_get_int(tab,
"dcd1_1",(cpl_size)i,&null);
412 dcd1_2 = cpl_table_get_int(tab,
"dcd1_2",(cpl_size)i,&null);
413 dcd2_1 = cpl_table_get_int(tab,
"dcd2_1",(cpl_size)i,&null);
414 dcd2_2 = cpl_table_get_int(tab,
"dcd2_2",(cpl_size)i,&null);
418 retval = vircam_chan_init(channum,ixmin,ixmax,iymin,iymax,dcrpix1,
419 dcrpix2,dcd1_1,dcd1_2,dcd2_1,dcd2_2,pp);
420 if (retval != CASU_OK) {
427 retval = vircam_chan_fill_lin(tab,i,pp);
428 if (retval != CASU_OK) {
465 for (i = 0; i < np; i++)
466 vircam_chan_close(*p+i);
503 ly = (int)(l/(p->delta_i));
504 lx = l - ly*(p->delta_i);
508 kx = (lx - p->Lx)*(p->dcd1_1) + (ly - p->Ly)*(p->dcd1_2);
509 ky = (lx - p->Lx)*(p->dcd2_1) + (ly - p->Ly)*(p->dcd2_2);
513 k = ky*(p->delta_x) + kx;
548 ky = (int)(k/(p->delta_x));
549 kx = k - ky*(p->delta_x);
553 lx = (kx*(p->dcd2_2) - ky*(p->dcd1_2))/(p->det_cd) + p->Lx;
554 ly = (ky*(p->dcd1_1) - kx*(p->dcd2_1))/(p->det_cd) + p->Ly;
558 l = ly*(p->delta_i) + lx;
594 ky = (int)(k/(p->delta_x));
595 kx = k - ky*(p->delta_x);
599 lx = (kx*(p->dcd2_2) - ky*(p->dcd1_2))/(p->det_cd) + p->Lx + p->ixmin - 1;
600 ly = (ky*(p->dcd1_1) - kx*(p->dcd2_1))/(p->det_cd) + p->Ly + p->iymin - 1;
604 l = ly*naxis[0] + lx;
662static int vircam_chan_init(
int channum,
int ixmin,
int ixmax,
int iymin,
663 int iymax,
int dcrpix1,
int dcrpix2,
int dcd1_1,
664 int dcd1_2,
int dcd2_1,
int dcd2_2, parquet *p) {
668 p->channum = channum;
677 (void)snprintf(p->imsec,SECSIZ,
"[%d:%d,%d:%d]",ixmin,ixmax,iymin,iymax);
678 p->delta_i = ixmax - ixmin + 1;
679 p->delta_j = iymax - iymin + 1;
680 if (dcrpix1 < 0 || dcrpix1 > p->delta_i ||
681 dcrpix2 < 0 || dcrpix2 > p->delta_j) {
682 cpl_msg_error(
"vircam_chan_init",
683 "nonsense values of dcrpix");
692 p->det_cd = dcd1_1*dcd2_2 - dcd1_2*dcd2_1;
693 p->delta_x = abs(dcd1_1*(p->delta_i) + dcd1_2*(p->delta_j));
694 p->delta_y = abs(dcd2_1*(p->delta_i) + dcd2_2*(p->delta_j));
719static void vircam_chan_close(parquet *p) {
753static int vircam_chan_testpos(cpl_table *intab,
const char *column) {
758 if (cpl_table_get_column_type(intab,column) != CPL_TYPE_INT)
764 nrows = (int)cpl_table_get_nrow(intab);
765 idata = cpl_table_get_data_int(intab,column);
766 for (i = 0; i < nrows; i++)
801static int vircam_chan_test1(cpl_table *intab,
const char *column) {
806 if (cpl_table_get_column_type(intab,column) != CPL_TYPE_INT)
812 nrows = (int)cpl_table_get_nrow(intab);
813 idata = cpl_table_get_data_int(intab,column);
814 for (i = 0; i < nrows; i++)
815 if (idata[i] != 0 && idata[i] != -1 && idata[i] != 1)
847static int vircam_chan_fill_lin(cpl_table *intab,
int row, parquet *p) {
852 p->norder = cpl_table_get_int(intab,
"norder",row,&null);
856 p->bb = cpl_malloc(p->norder*
sizeof(
double));
860 for (i = 1; i <= p->norder; i++) {
861 char * colname = cpl_sprintf(
"coeff_%d",i);
863 p->bb[i-1] = cpl_table_get_double(intab,colname,(cpl_size)row,&null);
cpl_table * vircam_chantab_new(int nord, cpl_table *template)
long vircam_chan_d2r(parquet *p, long l)
int vircam_chantab_verify(cpl_table *intab)
long vircam_chan_r2a(parquet *p, long naxis[2], long k)
int vircam_chan_fill(cpl_table *tab, parquet **p, long *np)
void vircam_chan_free(int np, parquet **p)
long vircam_chan_r2d(parquet *p, long k)