00001
00002
00003
00004
00005
00006
00007 #include <stdlib.h>
00008 #include <stdio.h>
00009 #include <string.h>
00010 #include <cpl.h>
00011
00012 #include "vircam_channel.h"
00013 #include "vircam_utils.h"
00014
00015
00016
00017
00018 #define NCHANTAB_COLS 15
00019 static const char *chantab_columns[] = {"channum",
00020 "ixmin",
00021 "ixmax",
00022 "iymin",
00023 "iymax",
00024 "dcrpix1",
00025 "dcrpix2",
00026 "dcd1_1",
00027 "dcd1_2",
00028 "dcd2_1",
00029 "dcd2_2",
00030 "lin_10000",
00031 "lin_10000_err",
00032 "norder",
00033 "coeff_1"};
00034
00035 static const cpl_type chantab_types[] = {CPL_TYPE_INT,
00036 CPL_TYPE_INT,
00037 CPL_TYPE_INT,
00038 CPL_TYPE_INT,
00039 CPL_TYPE_INT,
00040 CPL_TYPE_INT,
00041 CPL_TYPE_INT,
00042 CPL_TYPE_INT,
00043 CPL_TYPE_INT,
00044 CPL_TYPE_INT,
00045 CPL_TYPE_INT,
00046 CPL_TYPE_DOUBLE,
00047 CPL_TYPE_DOUBLE,
00048 CPL_TYPE_INT,
00049 CPL_TYPE_DOUBLE};
00050 #define NTESTPOSITIVE 7
00051 static const char *testpositive[] = {"channum",
00052 "ixmin",
00053 "ixmax",
00054 "iymin",
00055 "iymax",
00056 "dcrpix1",
00057 "dcrpix2"};
00058
00059 #define NTEST1 4
00060 static const char *test1[] = {"dcd1_1",
00061 "dcd1_2",
00062 "dcd2_1",
00063 "dcd2_2"};
00064
00065 #define SZCOL 9
00066
00067 static int vircam_chan_init(int channum, int ixmin, int ixmax, int iymin,
00068 int iymax, int dcrpix1, int dcrpix2, int dcd1_1,
00069 int dcd1_2, int dcd2_1, int dcd2_2, parquet *p);
00070 static void vircam_chan_close(parquet *p);
00071 static int vircam_chan_testpos(cpl_table *intab, const char *column);
00072 static int vircam_chan_test1(cpl_table *intab, const char *column);
00073 static int vircam_chan_fill_lin(cpl_table *intab, int row, parquet *p);
00074
00089
00112
00113
00114 extern int vircam_chantab_verify(cpl_table *intab) {
00115 int i,missing[NCHANTAB_COLS],wrongtype[NCHANTAB_COLS],ierr,norder;
00116 int nrows,null;
00117 double *c1;
00118 const char *fctid = "vircam_chantab_verify";
00119 char errmsg[1024],colname[SZCOL],msg[1024];
00120 const char *col;
00121
00122
00123
00124 errmsg[0] = '\0';
00125 if (intab == NULL) {
00126 cpl_msg_error(fctid,"Null input channel table");
00127 return(VIR_FATAL);
00128 }
00129
00130
00131
00132
00133 ierr = 0;
00134 for (i = 0; i < NCHANTAB_COLS; i++) {
00135 missing[i] = 0;
00136 wrongtype[i] = 0;
00137 if (cpl_table_has_column(intab,chantab_columns[i]) != 1) {
00138 missing[i] = 1;
00139 ierr = 1;
00140 } else if (cpl_table_get_column_type(intab,chantab_columns[i]) !=
00141 chantab_types[i]) {
00142 wrongtype[i] = 1;
00143 ierr = 1;
00144 }
00145 }
00146 if (ierr == 1) {
00147 (void)strcat(errmsg,"These columns are missing or have incorrect types");
00148 for (i = 0; i < NCHANTAB_COLS; i++) {
00149 if (missing[i] == 1) {
00150 (void)strcat(errmsg,"\n");
00151 (void)strcat(errmsg,chantab_columns[i]);
00152 (void)strcat(errmsg," Missing");
00153 } else if (wrongtype[i] == 1) {
00154 (void)strcat(errmsg,"\n");
00155 (void)strcat(errmsg,chantab_columns[i]);
00156 (void)strcat(errmsg," Wrong type");
00157 }
00158 }
00159 (void)strcat(errmsg,"\n");
00160 }
00161
00162
00163
00164
00165
00166 col = cpl_table_get_column_name(intab);
00167 while (col != NULL) {
00168 if (! strncmp(col,"coeff_",6)) {
00169 if (cpl_table_get_column_type(intab,col) != CPL_TYPE_DOUBLE) {
00170 (void)sprintf(msg,"Column %s must be double\n",col);
00171 (void)strcat(errmsg,msg);
00172 }
00173 }
00174 col = cpl_table_get_column_name(NULL);
00175 }
00176
00177
00178
00179
00180 ierr = 0;
00181 for (i = 0; i < NTESTPOSITIVE; i++) {
00182 missing[i] = 0;
00183 if (vircam_chan_testpos(intab,testpositive[i]) == VIR_OK)
00184 continue;
00185 ierr = 1;
00186 missing[i] = 1;
00187 }
00188 if (ierr == 1) {
00189 (void)strcat(errmsg,"These columns should be positive integers only:");
00190 for (i = 0; i < NTESTPOSITIVE; i++) {
00191 if (missing[i] == 1) {
00192 (void)strcat(errmsg,"\n");
00193 (void)strcat(errmsg,testpositive[i]);
00194 }
00195 }
00196 (void)strcat(errmsg,"\n");
00197 }
00198
00199
00200
00201 ierr = 0;
00202 for (i = 0; i < NTEST1; i++) {
00203 missing[i] = 0;
00204 if (vircam_chan_test1(intab,test1[i]) == VIR_OK)
00205 continue;
00206 ierr = 1;
00207 missing[i] = 1;
00208 }
00209 if (ierr == 1) {
00210 (void)strcat(errmsg,"These columns should be integers and (-1,0,1) only:");
00211 for (i = 0; i < NTEST1; i++) {
00212 if (missing[i] == 1) {
00213 (void)strcat(errmsg,"\n");
00214 (void)strcat(errmsg,test1[i]);
00215 }
00216 }
00217 (void)strcat(errmsg,"\n");
00218 }
00219
00220
00221
00222
00223
00224 norder = cpl_table_get_int(intab,"norder",0,&null);
00225 nrows = cpl_table_get_nrow(intab);
00226 c1 = cpl_table_get_data_double(intab,"coeff_1");
00227 for (i = 0; i < nrows; i++) {
00228 if (c1[i] != 1.0) {
00229 (void)strcat(errmsg,"\ncoeff_1 must be all 1s!\n");
00230 break;
00231 }
00232 }
00233 for (i = 2; i <= norder; i++) {
00234 missing[i] = 0;
00235 (void)snprintf(colname,SZCOL,"coeff_%d",i);
00236 if (cpl_table_has_column(intab,colname) != 1) {
00237 missing[i] = 1;
00238 ierr = 1;
00239 }
00240 }
00241 if (ierr == 1) {
00242 (void)strcat(errmsg,
00243 "\nThese coefficient columns are missing from the channel table:");
00244 for (i = 2; i < norder; i++) {
00245 if (missing[i] == 1) {
00246 (void)snprintf(colname,SZCOL,"coeff_%d",i);
00247 (void)strcat(errmsg,"\n");
00248 (void)strcat(errmsg,colname);
00249 }
00250 }
00251 (void)strcat(errmsg,"\n");
00252 }
00253
00254
00255
00256 if (errmsg[0] != '\0') {
00257 cpl_msg_error(fctid,"Errors in channel table\n%s",errmsg);
00258 return(VIR_FATAL);
00259 }
00260
00261
00262
00263 return(VIR_OK);
00264 }
00265
00266
00286
00287
00288 extern cpl_table *vircam_chantab_new(int nord, cpl_table *template) {
00289 cpl_table *tab;
00290 int i,oldnorder,null,j,nr;
00291 char colname[SZCOL];
00292
00293
00294
00295 tab = cpl_table_duplicate(template);
00296
00297
00298
00299
00300 oldnorder = cpl_table_get_int(tab,"norder",0,&null);
00301 if (oldnorder > nord) {
00302 for (i = nord+1; i <= oldnorder; i++) {
00303 (void)snprintf(colname,SZCOL,"coeff_%d",i);
00304 cpl_table_erase_column(tab,colname);
00305 }
00306 } else if (oldnorder < nord) {
00307 for (i = oldnorder+1; i <= nord; i++) {
00308 (void)snprintf(colname,SZCOL,"coeff_%d",i);
00309 if (cpl_table_has_column(tab,colname))
00310 continue;
00311 cpl_table_new_column(tab,colname,CPL_TYPE_DOUBLE);
00312 }
00313 }
00314
00315
00316
00317 nr = cpl_table_get_nrow(tab);
00318 for (i = 0; i < nr; i++) {
00319 cpl_table_set_int(tab,"norder",i,nord);
00320 cpl_table_set_double(tab,"coeff_1",i,1.0);
00321 for (j = 2; j <= nord; j++) {
00322 (void)snprintf(colname,SZCOL,"coeff_%d",j);
00323 cpl_table_set_double(tab,colname,i,0.0);
00324 }
00325 }
00326
00327
00328
00329 return(tab);
00330 }
00331
00332
00359
00360
00361 extern int vircam_chan_fill(cpl_table *tab, parquet **p, long *np) {
00362 parquet *pp;
00363 int i,channum,ixmin,ixmax,iymin,iymax;
00364 int dcrpix1,dcrpix2,dcd1_1,dcd1_2,dcd2_1,dcd2_2,retval,null;
00365
00366
00367
00368 if (vircam_chantab_verify(tab) != VIR_OK)
00369 return(VIR_FATAL);
00370
00371
00372
00373
00374 *np = cpl_table_get_nrow(tab);
00375 *p = cpl_malloc(*np*sizeof(parquet));
00376
00377
00378
00379 for (i = 0; i < *np; i++) {
00380 pp = *p + i;
00381 channum = cpl_table_get_int(tab,"channum",i,&null);
00382 ixmin = cpl_table_get_int(tab,"ixmin",i,&null);
00383 ixmax = cpl_table_get_int(tab,"ixmax",i,&null);
00384 iymin = cpl_table_get_int(tab,"iymin",i,&null);
00385 iymax = cpl_table_get_int(tab,"iymax",i,&null);
00386 dcrpix1 = cpl_table_get_int(tab,"dcrpix1",i,&null);
00387 dcrpix2 = cpl_table_get_int(tab,"dcrpix2",i,&null);
00388 dcd1_1 = cpl_table_get_int(tab,"dcd1_1",i,&null);
00389 dcd1_2 = cpl_table_get_int(tab,"dcd1_2",i,&null);
00390 dcd2_1 = cpl_table_get_int(tab,"dcd2_1",i,&null);
00391 dcd2_2 = cpl_table_get_int(tab,"dcd2_2",i,&null);
00392
00393
00394
00395 retval = vircam_chan_init(channum,ixmin,ixmax,iymin,iymax,dcrpix1,
00396 dcrpix2,dcd1_1,dcd1_2,dcd2_1,dcd2_2,pp);
00397 if (retval != VIR_OK) {
00398 freespace(*p);
00399 return(retval);
00400 }
00401
00402
00403
00404 retval = vircam_chan_fill_lin(tab,i,pp);
00405 if (retval != VIR_OK) {
00406 freespace(*p);
00407 return(retval);
00408 }
00409 }
00410
00411
00412
00413 return(VIR_OK);
00414 }
00415
00416
00435
00436
00437 extern void vircam_chan_free(int np, parquet **p) {
00438 int i;
00439
00440
00441
00442 for (i = 0; i < np; i++)
00443 vircam_chan_close(*p+i);
00444
00445
00446
00447 freespace(*p);
00448 }
00449
00450
00471
00472
00473 extern long vircam_chan_d2r(parquet *p, long l) {
00474 int lx,ly,kx,ky;
00475 long k;
00476
00477
00478
00479
00480 ly = (int)(l/(p->delta_i));
00481 lx = l - ly*(p->delta_i);
00482
00483
00484
00485 kx = (lx - p->Lx)*(p->dcd1_1) + (ly - p->Ly)*(p->dcd1_2);
00486 ky = (lx - p->Lx)*(p->dcd2_1) + (ly - p->Ly)*(p->dcd2_2);
00487
00488
00489
00490 k = ky*(p->delta_x) + kx;
00491 return(k);
00492 }
00493
00494
00516
00517
00518 extern long vircam_chan_r2d(parquet *p, long k) {
00519 int lx,ly,kx,ky;
00520 long l;
00521
00522
00523
00524
00525 ky = (int)(k/(p->delta_x));
00526 kx = k - ky*(p->delta_x);
00527
00528
00529
00530 lx = (kx*(p->dcd2_2) - ky*(p->dcd1_2))/(p->det_cd) + p->Lx;
00531 ly = (ky*(p->dcd1_1) - kx*(p->dcd2_1))/(p->det_cd) + p->Ly;
00532
00533
00534
00535 l = ly*(p->delta_i) + lx;
00536 return(l);
00537 }
00538
00539
00562
00563
00564 extern long vircam_chan_r2a(parquet *p, long naxis[2], long k) {
00565 int lx,ly,kx,ky;
00566 long l;
00567
00568
00569
00570
00571 ky = (int)(k/(p->delta_x));
00572 kx = k - ky*(p->delta_x);
00573
00574
00575
00576 lx = (kx*(p->dcd2_2) - ky*(p->dcd1_2))/(p->det_cd) + p->Lx + p->ixmin - 1;
00577 ly = (ky*(p->dcd1_1) - kx*(p->dcd2_1))/(p->det_cd) + p->Ly + p->iymin - 1;
00578
00579
00580
00581 l = ly*naxis[0] + lx;
00582 return(l);
00583 }
00584
00585
00586
00636
00637
00638
00639 static int vircam_chan_init(int channum, int ixmin, int ixmax, int iymin,
00640 int iymax, int dcrpix1, int dcrpix2, int dcd1_1,
00641 int dcd1_2, int dcd2_1, int dcd2_2, parquet *p) {
00642
00643
00644
00645 p->channum = channum;
00646 p->ixmin = ixmin;
00647 p->ixmax = ixmax;
00648 p->iymin = iymin;
00649 p->iymax = iymax;
00650 p->fpix[0] = ixmin;
00651 p->fpix[1] = iymin;
00652 p->lpix[0] = ixmax;
00653 p->lpix[1] = iymax;
00654 (void)snprintf(p->imsec,SECSIZ,"[%d:%d,%d:%d]",ixmin,ixmax,iymin,iymax);
00655 p->delta_i = ixmax - ixmin + 1;
00656 p->delta_j = iymax - iymin + 1;
00657 if (dcrpix1 < 0 || dcrpix1 > p->delta_i ||
00658 dcrpix2 < 0 || dcrpix2 > p->delta_j) {
00659 cpl_msg_error("vircam_chan_init",
00660 "nonsense values of dcrpix");
00661 return(VIR_FATAL);
00662 }
00663 p->Lx = dcrpix1 - 1;
00664 p->Ly = dcrpix2 - 1;
00665 p->dcd1_1 = dcd1_1;
00666 p->dcd1_2 = dcd1_2;
00667 p->dcd2_1 = dcd2_1;
00668 p->dcd2_2 = dcd2_2;
00669 p->det_cd = dcd1_1*dcd2_2 - dcd1_2*dcd2_1;
00670 p->delta_x = abs(dcd1_1*(p->delta_i) + dcd1_2*(p->delta_j));
00671 p->delta_y = abs(dcd2_1*(p->delta_i) + dcd2_2*(p->delta_j));
00672 p->data = NULL;
00673 p->norder = 0;
00674 p->bb = NULL;
00675 return(VIR_OK);
00676 }
00677
00678
00694
00695
00696 static void vircam_chan_close(parquet *p) {
00697
00698
00699
00700
00701 freespace(p->data);
00702 freespace(p->bb);
00703 }
00704
00705
00728
00729
00730 static int vircam_chan_testpos(cpl_table *intab, const char *column) {
00731 int nrows,i,*idata;
00732
00733
00734
00735 if (cpl_table_get_column_type(intab,column) != CPL_TYPE_INT)
00736 return(VIR_FATAL);
00737
00738
00739
00740
00741 nrows = cpl_table_get_nrow(intab);
00742 idata = cpl_table_get_data_int(intab,column);
00743 for (i = 0; i < nrows; i++)
00744 if (idata[i] <= 0)
00745 return(VIR_FATAL);
00746
00747
00748
00749 return(VIR_OK);
00750 }
00751
00752
00776
00777
00778 static int vircam_chan_test1(cpl_table *intab, const char *column) {
00779 int nrows,i,*idata;
00780
00781
00782
00783 if (cpl_table_get_column_type(intab,column) != CPL_TYPE_INT)
00784 return(VIR_FATAL);
00785
00786
00787
00788
00789 nrows = cpl_table_get_nrow(intab);
00790 idata = cpl_table_get_data_int(intab,column);
00791 for (i = 0; i < nrows; i++)
00792 if (idata[i] != 0 && idata[i] != -1 && idata[i] != 1)
00793 return(VIR_FATAL);
00794
00795
00796
00797 return(VIR_OK);
00798 }
00799
00800
00822
00823
00824 static int vircam_chan_fill_lin(cpl_table *intab, int row, parquet *p) {
00825 int i,null;
00826 char colname[SZCOL];
00827
00828
00829
00830 p->norder = cpl_table_get_int(intab,"norder",row,&null);
00831
00832
00833
00834 p->bb = cpl_malloc(p->norder*sizeof(double));
00835
00836
00837
00838 for (i = 1; i <= p->norder; i++) {
00839 (void)snprintf(colname,SZCOL,"coeff_%d",i);
00840 p->bb[i-1] = cpl_table_get_double(intab,colname,row,&null);
00841 }
00842 return(VIR_OK);
00843 }
00844
00845
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890